From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by spool.mail.gandi.net (Postfix) with ESMTPS id 85EC8AC1748 for ; Tue, 25 Jul 2023 23:38:43 +0000 (UTC) DKIM-Signature: a=rsa-sha256; bh=EotQ5G6O7s0IF0RDAF1HlQdoYw6zJh8V7cflIabW2V8=; c=relaxed/simple; d=groups.io; h=X-Received:X-Received:ARC-Seal:ARC-Message-Signature:ARC-Authentication-Results:X-Received:X-Received:X-MS-Exchange-Authentication-Results:Received-SPF:X-Received:X-Received:X-Received:X-Received:From:To:CC:Subject:Date:Message-ID:In-Reply-To:References:X-NVConfidentiality:MIME-Version:X-NV-OnPremToCloud:X-EOPAttributedMessage:X-MS-PublicTrafficType:X-MS-TrafficTypeDiagnostic:X-MS-Office365-Filtering-Correlation-Id:X-MS-Exchange-SenderADCheck:X-MS-Exchange-AntiSpam-Relay:X-Microsoft-Antispam-Message-Info:X-OriginatorOrg:X-MS-Exchange-CrossTenant-OriginalArrivalTime:X-MS-Exchange-CrossTenant-Network-Message-Id:X-MS-Exchange-CrossTenant-Id:X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp:X-MS-Exchange-CrossTenant-AuthSource:X-MS-Exchange-CrossTenant-AuthAs:X-MS-Exchange-CrossTenant-FromEntityHeader:X-MS-Exchange-Transport-CrossTenantHeadersStamped:Precedence:List-Subscribe:List-Help:Sender:List-Id:Mailing-List:Delivered-To:Reply-To:List-Unsubscribe-Post:List-Unsubscrib e:X-Gm-Message-State:Content-Type; s=20140610; t=1690328322; v=1; b=U08m9tnwOlbtXkJ+DOKqGycPm5bZ9NsOQ1UQuVZMqMntj5DrraCcGSSZ38KbhQDyOXFJu027 xq4BnhhSn65z0bifH4xN7k14nyWY1/zWFSI4x829jQc065+sm1mENUK1nVU3D4r40vd2LI/ZS10 fRCE84mzfJDhJftJU/NnIyMM= X-Received: by 127.0.0.2 with SMTP id TkO5YY7687511xhOqDKMGlPT; Tue, 25 Jul 2023 16:38:42 -0700 X-Received: from NAM12-BN8-obe.outbound.protection.outlook.com (NAM12-BN8-obe.outbound.protection.outlook.com [40.107.237.71]) by mx.groups.io with SMTP id smtpd.web11.107.1690328321156784208 for ; Tue, 25 Jul 2023 16:38:41 -0700 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=XFGoTrhRxvKtRfQRIQWAduOmAO2C4HYuSHhj0MWTTAzKSA0waF8FDBaXDNJQPOLzSapPByCf61asxM/TJPxsS8V6DbaxKrlXDOiW/PHdrCSH9sB+exd8xSFlM2ksrxYS4VMgPlJOn3Doa1DUPBvxLsbxpe+YgHMUE9vTQtuNcYqlfNCjEDXu6pSGA6DxYssBAgWY7OrFIbk/EpxcRo9l6KPcNoADCk6wJAMUp1AVLAndAFXCCDvq3oq9jH81SVPkRFoi5lPX5Gl6BTkW6vmDlVGgFVtfw7GzOauBA16E8fdsRa8pKqb7vGwzFaeSUnVld4FKE5AFY0KZuVBG7M1cKQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=RLu7Ye2HsMXx7k2CIGO84jY8nFuU5YsqN7/erSzajzI=; b=Lp5GuGz5Dblwr/GkE2EJtIiaOclG2+52LkpPcLJaMuz2eQ84FJmvFCGn+VLgsnQ+emTFz8m6FdkA7LX2+iF0IYp6DJc0iL5VKPyvjVBFBDZCKxvoxRlwws9cI09aCJV+rYJTzNqHsSxpuZl6Y1fxT0zRYKHoTa8OJYSVGzzQUvVdxf9pTN+jTt1HMTTPI8lNvToe4/lOmrraYhGNnGfARk1h9Fc5bozyFg5+dSuNCgW/ziIl5CzY90Mj6VfZNhn/BppQyAErx+CE3Rd6kar6M+FnR92PulTStDsiVVq3twfydHer2q/BTzL5YeZzabUcPFzSgZ6izcBs5VSBCKNltQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 216.228.117.160) smtp.rcpttodomain=edk2.groups.io smtp.mailfrom=nvidia.com; dmarc=pass (p=reject sp=reject pct=100) action=none header.from=nvidia.com; dkim=none (message not signed); arc=none X-Received: from MW4PR03CA0174.namprd03.prod.outlook.com (2603:10b6:303:8d::29) by MN2PR12MB4222.namprd12.prod.outlook.com (2603:10b6:208:19a::21) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6609.33; Tue, 25 Jul 2023 23:38:36 +0000 X-Received: from CO1NAM11FT026.eop-nam11.prod.protection.outlook.com (2603:10b6:303:8d:cafe::b7) by MW4PR03CA0174.outlook.office365.com (2603:10b6:303:8d::29) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6609.33 via Frontend Transport; Tue, 25 Jul 2023 23:38:36 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 216.228.117.160) smtp.mailfrom=nvidia.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=nvidia.com; Received-SPF: Pass (protection.outlook.com: domain of nvidia.com designates 216.228.117.160 as permitted sender) receiver=protection.outlook.com; client-ip=216.228.117.160; helo=mail.nvidia.com; pr=C X-Received: from mail.nvidia.com (216.228.117.160) by CO1NAM11FT026.mail.protection.outlook.com (10.13.175.67) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6631.29 via Frontend Transport; Tue, 25 Jul 2023 23:38:36 +0000 X-Received: from rnnvmail201.nvidia.com (10.129.68.8) by mail.nvidia.com (10.129.200.66) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.986.5; Tue, 25 Jul 2023 16:38:23 -0700 X-Received: from rnnvmail201.nvidia.com (10.129.68.8) by rnnvmail201.nvidia.com (10.129.68.8) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.986.37; Tue, 25 Jul 2023 16:38:23 -0700 X-Received: from build-gmahadevan-20230109T020417557.nvidia.com (10.127.8.12) by mail.nvidia.com (10.129.68.8) with Microsoft SMTP Server id 15.2.986.37 via Frontend Transport; Tue, 25 Jul 2023 16:38:22 -0700 From: "Girish Mahadevan via groups.io" To: , CC: , , , , , Subject: [edk2-devel] [PATCH v3 2/5] DynamicTablesPkg: Split the ACPI and SMBIOS table generators Date: Tue, 25 Jul 2023 23:38:02 +0000 Message-ID: <20230725233805.646668-3-gmahadevan@nvidia.com> In-Reply-To: <20230725233805.646668-1-gmahadevan@nvidia.com> References: <20230725233805.646668-1-gmahadevan@nvidia.com> X-NVConfidentiality: public MIME-Version: 1.0 X-NV-OnPremToCloud: ExternallySecured X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: CO1NAM11FT026:EE_|MN2PR12MB4222:EE_ X-MS-Office365-Filtering-Correlation-Id: 34619001-9029-4da4-c9e3-08db8d684446 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam-Message-Info: PQDFQFo1Ja+ar772ds0B10Tz+uCdS2qm34T+SXs9+u035TUlo3JQC6gOhsUpMA4/INj/Tq75kjxIgOEw9ZR9YSLrvd5qWmAyxLyvLSfrKTss5LAxgpfH1wIUyHe1msw6gSUipRdE+gsWeGAW/4DgEU2R2P1S5snNGE92DjfynDuManHo5kQ2GdwIPs8k9nvO6vrz6wtXumEH5Z9PI6StQPT5fHBFLhUt226ILbHly08TEy+wyrXXSNkQA/79N+obqCopLLlgwuhU3MGJVgnYoTSHJzWnvdFOzwQlbxUKylvlM/ogETLzCbP47+PLuAfrzm7V9KsmI6cRlhyVCKyEkTLyWS+Tc/P+xeoZFNOWNTGbP0EwWYL9t8GFEwfQQL7ZQLweIoa+FGT3uRa0l1jEe9eBH4tJX8pYSbuQAiCcYl/lkIcQewyRCeBgfpir05Ee9w7JNvn4s2K1mWjk6N92LwrZP5NrGDMFzN2RCdw+q5MIw6AQZ3/Clap5ElSBhYNpDLSzBvULSpYd682CZLdteyjK1DkPBAIA2kfdA2VDupyk0hEi/IIshNnQXffy8TvUJ/HAXQpz02W+QKTPUvL/iLqVb0zG+6+LD/t2YQrNmZDsOHNjtrYBs8njfhKY5wCRdcfhVbXHi42rWShQ2ZStLSwzccrBhWrv60FEzwdv7RUoiSAITtQGUGpooDc75cm0Im0lYEFM80QyG1Vq2RAFyh3NMmnnfpTBSft9koEZWHGjpjY7KnI9i9XlzLeMQUcp X-OriginatorOrg: Nvidia.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 25 Jul 2023 23:38:36.3880 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 34619001-9029-4da4-c9e3-08db8d684446 X-MS-Exchange-CrossTenant-Id: 43083d15-7273-40c1-b7db-39efd9ccc17a X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=43083d15-7273-40c1-b7db-39efd9ccc17a;Ip=[216.228.117.160];Helo=[mail.nvidia.com] X-MS-Exchange-CrossTenant-AuthSource: CO1NAM11FT026.eop-nam11.prod.protection.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: MN2PR12MB4222 Precedence: Bulk List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,gmahadevan@nvidia.com List-Unsubscribe-Post: List-Unsubscribe=One-Click List-Unsubscribe: X-Gm-Message-State: JEGlMIl4ting8qgcD0TNs0qQx7686176AA= Content-Type: text/plain X-GND-Status: LEGIT Authentication-Results: spool.mail.gandi.net; dkim=pass header.d=groups.io header.s=20140610 header.b=U08m9tnw; arc=reject ("signature check failed: fail, {[1] = sig:microsoft.com:reject}"); dmarc=none; spf=pass (spool.mail.gandi.net: domain of bounce@groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce@groups.io Split the SMBIOS and ACPI table generators into their own files. Signed-off-by: Girish Mahadevan Reviewed-by: Jeff Brasen --- .../DynamicTableManagerDxe/AcpiTableBuilder.c | 798 ++++++++++ .../DynamicTableManagerDxe.c | 1356 +---------------- .../DynamicTableManagerDxe.inf | 2 + .../SmbiosTableBuilder.c | 606 ++++++++ 4 files changed, 1419 insertions(+), 1343 deletions(-) create mode 100644 DynamicTablesPkg/Drivers/DynamicTableManagerDxe/AcpiTableBuilder.c create mode 100644 DynamicTablesPkg/Drivers/DynamicTableManagerDxe/SmbiosTableBuilder.c diff --git a/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/AcpiTableBuilder.c b/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/AcpiTableBuilder.c new file mode 100644 index 0000000000..2adfb0378e --- /dev/null +++ b/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/AcpiTableBuilder.c @@ -0,0 +1,798 @@ +/** @file + Acpi Table Manager Dxe + + Copyright (c) 2017 - 2019, ARM Limited. All rights reserved. + Copyright (c) 2022 - 2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved. + + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include +#include +#include +#include +#include + +// Module specific include files. +#include +#include +#include +#include +#include +#include +#include + +/// +/// Bit definitions for acceptable ACPI table presence formats. +/// Currently only ACPI tables present in the ACPI info list and +/// already installed will count towards "Table Present" during +/// verification routine. +/// +#define ACPI_TABLE_PRESENT_INFO_LIST BIT0 +#define ACPI_TABLE_PRESENT_INSTALLED BIT1 + +/// +/// Order of ACPI table being verified during presence inspection. +/// +#define ACPI_TABLE_VERIFY_FADT 0 +#define ACPI_TABLE_VERIFY_MADT 1 +#define ACPI_TABLE_VERIFY_GTDT 2 +#define ACPI_TABLE_VERIFY_DSDT 3 +#define ACPI_TABLE_VERIFY_DBG2 4 +#define ACPI_TABLE_VERIFY_SPCR 5 +#define ACPI_TABLE_VERIFY_COUNT 6 + +/// +/// Private data structure to verify the presence of mandatory +/// or optional ACPI tables. +/// +typedef struct { + /// ESTD ID for the ACPI table of interest. + ESTD_ACPI_TABLE_ID EstdTableId; + /// Standard UINT32 ACPI signature. + UINT32 AcpiTableSignature; + /// 4 character ACPI table name (the 5th char8 is for null terminator). + CHAR8 AcpiTableName[sizeof (UINT32) + 1]; + /// Indicator on whether the ACPI table is required. + BOOLEAN IsMandatory; + /// Formats of verified presences, as defined by ACPI_TABLE_PRESENT_* + /// This field should be initialized to 0 and will be populated during + /// verification routine. + UINT16 Presence; +} ACPI_TABLE_PRESENCE_INFO; + +/// +/// We require the FADT, MADT, GTDT and the DSDT tables to boot. +/// This list also include optional ACPI tables: DBG2, SPCR. +/// +ACPI_TABLE_PRESENCE_INFO mAcpiVerifyTables[ACPI_TABLE_VERIFY_COUNT] = { + { EStdAcpiTableIdFadt, EFI_ACPI_6_2_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE, "FADT", TRUE, 0 }, + { EStdAcpiTableIdMadt, EFI_ACPI_6_2_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE, "MADT", TRUE, 0 }, + { EStdAcpiTableIdGtdt, EFI_ACPI_6_2_GENERIC_TIMER_DESCRIPTION_TABLE_SIGNATURE, "GTDT", TRUE, 0 }, + { EStdAcpiTableIdDsdt, EFI_ACPI_6_2_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE, "DSDT", TRUE, 0 }, + { EStdAcpiTableIdDbg2, EFI_ACPI_6_2_DEBUG_PORT_2_TABLE_SIGNATURE, "DBG2", FALSE, 0 }, + { EStdAcpiTableIdSpcr, EFI_ACPI_6_2_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_SIGNATURE, "SPCR", FALSE, 0 }, +}; + +/** This macro expands to a function that retrieves the ACPI Table + List from the Configuration Manager. +*/ +GET_OBJECT_LIST ( + EObjNameSpaceStandard, + EStdObjAcpiTableList, + CM_STD_OBJ_ACPI_TABLE_INFO + ) + +/** A helper function to build and install a single ACPI table. + + This is a helper function that invokes the Table generator interface + for building an ACPI table. It uses the AcpiTableProtocol to install the + table, then frees the resources allocated for generating it. + + @param [in] TableFactoryProtocol Pointer to the Table Factory Protocol + interface. + @param [in] CfgMgrProtocol Pointer to the Configuration Manager + Protocol Interface. + @param [in] Generator Pointer to the AcpiTable generator. + @param [in] AcpiTableProtocol Pointer to the AcpiTable protocol. + @param [in] AcpiTableInfo Pointer to the ACPI table Info. + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER A parameter is invalid. + @retval EFI_NOT_FOUND Required object is not found. + @retval EFI_BAD_BUFFER_SIZE Size returned by the Configuration Manager + is less than the Object size for the + requested object. +**/ +STATIC +EFI_STATUS +EFIAPI +BuildAndInstallSingleAcpiTable ( + IN CONST EDKII_DYNAMIC_TABLE_FACTORY_PROTOCOL *CONST TableFactoryProtocol, + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, + IN CONST ACPI_TABLE_GENERATOR *CONST Generator, + IN EFI_ACPI_TABLE_PROTOCOL *AcpiTableProtocol, + IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo + ) +{ + EFI_STATUS Status; + EFI_STATUS Status1; + EFI_ACPI_DESCRIPTION_HEADER *AcpiTable; + UINTN TableHandle; + + AcpiTable = NULL; + Status = Generator->BuildAcpiTable ( + Generator, + AcpiTableInfo, + CfgMgrProtocol, + &AcpiTable + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: Failed to Build Table." \ + " TableGeneratorId = 0x%x. Status = %r\n", + AcpiTableInfo->TableGeneratorId, + Status + )); + // Free any allocated resources. + goto exit_handler; + } + + if (AcpiTable == NULL) { + Status = EFI_NOT_FOUND; + goto exit_handler; + } + + // Dump ACPI Table Header + DUMP_ACPI_TABLE_HEADER (AcpiTable); + + // Install ACPI table + Status = AcpiTableProtocol->InstallAcpiTable ( + AcpiTableProtocol, + AcpiTable, + AcpiTable->Length, + &TableHandle + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: Failed to Install ACPI Table. Status = %r\n", + Status + )); + // Free any allocated resources. + goto exit_handler; + } + + DEBUG (( + DEBUG_INFO, + "INFO: ACPI Table installed. Status = %r\n", + Status + )); + +exit_handler: + // Free any resources allocated for generating the tables. + if (Generator->FreeTableResources != NULL) { + Status1 = Generator->FreeTableResources ( + Generator, + AcpiTableInfo, + CfgMgrProtocol, + &AcpiTable + ); + if (EFI_ERROR (Status1)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: Failed to Free Table Resources." \ + "TableGeneratorId = 0x%x. Status = %r\n", + AcpiTableInfo->TableGeneratorId, + Status1 + )); + } + + // Return the first error status in case of failure + if (!EFI_ERROR (Status)) { + Status = Status1; + } + } + + return Status; +} + +/** A helper function to build and install multiple ACPI tables. + + This is a helper function that invokes the Table generator interface + for building an ACPI table. It uses the AcpiTableProtocol to install the + table, then frees the resources allocated for generating it. + + @param [in] TableFactoryProtocol Pointer to the Table Factory Protocol + interface. + @param [in] CfgMgrProtocol Pointer to the Configuration Manager + Protocol Interface. + @param [in] Generator Pointer to the AcpiTable generator. + @param [in] AcpiTableProtocol Pointer to the AcpiTable protocol. + @param [in] AcpiTableInfo Pointer to the ACPI table Info. + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER A parameter is invalid. + @retval EFI_NOT_FOUND Required object is not found. + @retval EFI_BAD_BUFFER_SIZE Size returned by the Configuration Manager + is less than the Object size for the + requested object. +**/ +STATIC +EFI_STATUS +EFIAPI +BuildAndInstallMultipleAcpiTable ( + IN CONST EDKII_DYNAMIC_TABLE_FACTORY_PROTOCOL *CONST TableFactoryProtocol, + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, + IN CONST ACPI_TABLE_GENERATOR *CONST Generator, + IN EFI_ACPI_TABLE_PROTOCOL *AcpiTableProtocol, + IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo + ) +{ + EFI_STATUS Status; + EFI_STATUS Status1; + EFI_ACPI_DESCRIPTION_HEADER **AcpiTable; + UINTN TableCount; + UINTN TableHandle; + UINTN Index; + + AcpiTable = NULL; + TableCount = 0; + Status = Generator->BuildAcpiTableEx ( + Generator, + AcpiTableInfo, + CfgMgrProtocol, + &AcpiTable, + &TableCount + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: Failed to Build Table." \ + " TableGeneratorId = 0x%x. Status = %r\n", + AcpiTableInfo->TableGeneratorId, + Status + )); + // Free any allocated resources. + goto exit_handler; + } + + if ((AcpiTable == NULL) || (TableCount == 0)) { + Status = EFI_NOT_FOUND; + goto exit_handler; + } + + for (Index = 0; Index < TableCount; Index++) { + // Dump ACPI Table Header + DUMP_ACPI_TABLE_HEADER (AcpiTable[Index]); + // Install ACPI table + Status = AcpiTableProtocol->InstallAcpiTable ( + AcpiTableProtocol, + AcpiTable[Index], + AcpiTable[Index]->Length, + &TableHandle + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: Failed to Install ACPI Table. Status = %r\n", + Status + )); + // Free any allocated resources. + goto exit_handler; + } + + DEBUG (( + DEBUG_INFO, + "INFO: ACPI Table installed. Status = %r\n", + Status + )); + } + +exit_handler: + // Free any resources allocated for generating the tables. + if (Generator->FreeTableResourcesEx != NULL) { + Status1 = Generator->FreeTableResourcesEx ( + Generator, + AcpiTableInfo, + CfgMgrProtocol, + &AcpiTable, + TableCount + ); + if (EFI_ERROR (Status1)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: Failed to Free Table Resources." \ + "TableGeneratorId = 0x%x. Status = %r\n", + AcpiTableInfo->TableGeneratorId, + Status1 + )); + } + + // Return the first error status in case of failure + if (!EFI_ERROR (Status)) { + Status = Status1; + } + } + + return Status; +} + +/** A helper function to invoke a Table generator + + This is a helper function that invokes the Table generator interface + for building an ACPI table. It uses the AcpiTableProtocol to install the + table, then frees the resources allocated for generating it. + + @param [in] TableFactoryProtocol Pointer to the Table Factory Protocol + interface. + @param [in] CfgMgrProtocol Pointer to the Configuration Manager + Protocol Interface. + @param [in] AcpiTableProtocol Pointer to the AcpiTable protocol. + @param [in] AcpiTableInfo Pointer to the ACPI table Info. + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER A parameter is invalid. + @retval EFI_NOT_FOUND Required object is not found. + @retval EFI_BAD_BUFFER_SIZE Size returned by the Configuration Manager + is less than the Object size for the + requested object. +**/ +STATIC +EFI_STATUS +EFIAPI +BuildAndInstallAcpiTable ( + IN CONST EDKII_DYNAMIC_TABLE_FACTORY_PROTOCOL *CONST TableFactoryProtocol, + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, + IN EFI_ACPI_TABLE_PROTOCOL *AcpiTableProtocol, + IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo + ) +{ + EFI_STATUS Status; + CONST ACPI_TABLE_GENERATOR *Generator; + + ASSERT (TableFactoryProtocol != NULL); + ASSERT (CfgMgrProtocol != NULL); + ASSERT (AcpiTableProtocol != NULL); + ASSERT (AcpiTableInfo != NULL); + + DEBUG (( + DEBUG_INFO, + "INFO: EStdObjAcpiTableList: Address = 0x%p," \ + " TableGeneratorId = 0x%x\n", + AcpiTableInfo, + AcpiTableInfo->TableGeneratorId + )); + + Generator = NULL; + Status = TableFactoryProtocol->GetAcpiTableGenerator ( + TableFactoryProtocol, + AcpiTableInfo->TableGeneratorId, + &Generator + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: Table Generator not found." \ + " TableGeneratorId = 0x%x. Status = %r\n", + AcpiTableInfo->TableGeneratorId, + Status + )); + return Status; + } + + if (Generator == NULL) { + return EFI_NOT_FOUND; + } + + DEBUG (( + DEBUG_INFO, + "INFO: Generator found : %s\n", + Generator->Description + )); + + if (Generator->BuildAcpiTableEx != NULL) { + Status = BuildAndInstallMultipleAcpiTable ( + TableFactoryProtocol, + CfgMgrProtocol, + Generator, + AcpiTableProtocol, + AcpiTableInfo + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: Failed to find build and install ACPI Table." \ + " Status = %r\n", + Status + )); + } + } else if (Generator->BuildAcpiTable != NULL) { + Status = BuildAndInstallSingleAcpiTable ( + TableFactoryProtocol, + CfgMgrProtocol, + Generator, + AcpiTableProtocol, + AcpiTableInfo + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: Failed to find build and install ACPI Table." \ + " Status = %r\n", + Status + )); + } + } else { + Status = EFI_INVALID_PARAMETER; + DEBUG (( + DEBUG_ERROR, + "ERROR: Table Generator does not implement the" \ + " ACPI_TABLE_GENERATOR_BUILD_TABLE interface." \ + " TableGeneratorId = 0x%x. Status = %r\n", + AcpiTableInfo->TableGeneratorId, + Status + )); + } + + return Status; +} + +/** The function checks if the Configuration Manager has provided the + mandatory ACPI tables for installation. + + @param [in] AcpiTableInfo Pointer to the ACPI Table Info list. + @param [in] AcpiTableCount Count of ACPI Table Info. + + @retval EFI_SUCCESS Success. + @retval EFI_NOT_FOUND If mandatory table is not found. + @retval EFI_ALREADY_STARTED If mandatory table found in AcpiTableInfo is already installed. +**/ +STATIC +EFI_STATUS +EFIAPI +VerifyMandatoryTablesArePresent ( + IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo, + IN UINT32 AcpiTableCount + ) +{ + EFI_STATUS Status; + UINTN Handle; + UINTN Index; + UINTN InstalledTableIndex; + EFI_ACPI_DESCRIPTION_HEADER *DescHeader; + EFI_ACPI_TABLE_VERSION Version; + EFI_ACPI_SDT_PROTOCOL *AcpiSdt; + + ASSERT (AcpiTableInfo != NULL); + + Status = EFI_SUCCESS; + + // Check against the statically initialized ACPI tables to see if they are in ACPI info list + while (AcpiTableCount-- != 0) { + for (Index = 0; Index < ACPI_TABLE_VERIFY_COUNT; Index++) { + if (AcpiTableInfo[AcpiTableCount].AcpiTableSignature == mAcpiVerifyTables[Index].AcpiTableSignature) { + mAcpiVerifyTables[Index].Presence |= ACPI_TABLE_PRESENT_INFO_LIST; + // Found this table, skip the rest. + break; + } + } + } + + // They also might be published already, so we can search from there + if (FeaturePcdGet (PcdInstallAcpiSdtProtocol)) { + AcpiSdt = NULL; + Status = gBS->LocateProtocol (&gEfiAcpiSdtProtocolGuid, NULL, (VOID **)&AcpiSdt); + + if (EFI_ERROR (Status) || (AcpiSdt == NULL)) { + DEBUG ((DEBUG_ERROR, "ERROR: Failed to locate ACPI SDT protocol (0x%p) - %r\n", AcpiSdt, Status)); + return Status; + } + + for (Index = 0; Index < ACPI_TABLE_VERIFY_COUNT; Index++) { + Handle = 0; + InstalledTableIndex = 0; + do { + Status = AcpiSdt->GetAcpiTable (InstalledTableIndex, (EFI_ACPI_SDT_HEADER **)&DescHeader, &Version, &Handle); + if (EFI_ERROR (Status)) { + break; + } + + InstalledTableIndex++; + } while (DescHeader->Signature != mAcpiVerifyTables[Index].AcpiTableSignature); + + if (!EFI_ERROR (Status)) { + mAcpiVerifyTables[Index].Presence |= ACPI_TABLE_PRESENT_INSTALLED; + } + } + } + + // Reset the return Status value to EFI_SUCCESS. We do not fully care if the table look up has failed. + Status = EFI_SUCCESS; + for (Index = 0; Index < ACPI_TABLE_VERIFY_COUNT; Index++) { + if (mAcpiVerifyTables[Index].Presence == 0) { + if (mAcpiVerifyTables[Index].IsMandatory) { + DEBUG ((DEBUG_ERROR, "ERROR: %a Table not found.\n", mAcpiVerifyTables[Index].AcpiTableName)); + Status = EFI_NOT_FOUND; + } else { + DEBUG ((DEBUG_WARN, "WARNING: %a Table not found.\n", mAcpiVerifyTables[Index].AcpiTableName)); + } + } else if (mAcpiVerifyTables[Index].Presence == + (ACPI_TABLE_PRESENT_INFO_LIST | ACPI_TABLE_PRESENT_INSTALLED)) + { + DEBUG ((DEBUG_ERROR, "ERROR: %a Table found while already published.\n", mAcpiVerifyTables[Index].AcpiTableName)); + Status = EFI_ALREADY_STARTED; + } + } + + return Status; +} + +/** Generate and install ACPI tables. + + The function gathers the information necessary for installing the + ACPI tables from the Configuration Manager, invokes the generators + and installs them (via BuildAndInstallAcpiTable). + + @param [in] TableFactoryProtocol Pointer to the Table Factory Protocol + interface. + @param [in] CfgMgrProtocol Pointer to the Configuration Manager + Protocol Interface. + + @retval EFI_SUCCESS Success. + @retval EFI_NOT_FOUND If a mandatory table or a generator is not found. + @retval EFI_ALREADY_STARTED If mandatory table found in AcpiTableInfo is already installed. +**/ +STATIC +EFI_STATUS +EFIAPI +ProcessAcpiTables ( + IN CONST EDKII_DYNAMIC_TABLE_FACTORY_PROTOCOL *CONST TableFactoryProtocol, + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol + ) +{ + EFI_STATUS Status; + EFI_ACPI_TABLE_PROTOCOL *AcpiTableProtocol; + CM_STD_OBJ_ACPI_TABLE_INFO *AcpiTableInfo; + UINT32 AcpiTableCount; + UINT32 Idx; + + ASSERT (TableFactoryProtocol != NULL); + ASSERT (CfgMgrProtocol != NULL); + + // Find the AcpiTable protocol + Status = gBS->LocateProtocol ( + &gEfiAcpiTableProtocolGuid, + NULL, + (VOID **)&AcpiTableProtocol + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: Failed to find AcpiTable protocol. Status = %r\n", + Status + )); + return Status; + } + + Status = GetEStdObjAcpiTableList ( + CfgMgrProtocol, + CM_NULL_TOKEN, + &AcpiTableInfo, + &AcpiTableCount + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: Failed to get ACPI Table List. Status = %r\n", + Status + )); + return Status; + } + + if (0 == AcpiTableCount) { + DEBUG (( + DEBUG_ERROR, + "ERROR: EStdObjAcpiTableList: AcpiTableCount = %d\n", + AcpiTableCount + )); + return EFI_NOT_FOUND; + } + + DEBUG (( + DEBUG_INFO, + "INFO: EStdObjAcpiTableList: AcpiTableCount = %d\n", + AcpiTableCount + )); + + // Check if mandatory ACPI tables are present. + Status = VerifyMandatoryTablesArePresent ( + AcpiTableInfo, + AcpiTableCount + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: Failed to verify mandatory ACPI Table(s) presence." + " Status = %r\n", + Status + )); + return Status; + } + + // Add the FADT Table first. + if ((mAcpiVerifyTables[ACPI_TABLE_VERIFY_FADT].Presence & ACPI_TABLE_PRESENT_INSTALLED) == 0) { + // FADT is not yet installed + for (Idx = 0; Idx < AcpiTableCount; Idx++) { + if (CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdFadt) == + AcpiTableInfo[Idx].TableGeneratorId) + { + Status = BuildAndInstallAcpiTable ( + TableFactoryProtocol, + CfgMgrProtocol, + AcpiTableProtocol, + &AcpiTableInfo[Idx] + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: Failed to find build and install ACPI FADT Table." \ + " Status = %r\n", + Status + )); + return Status; + } + + break; + } + } // for + } + + // Add remaining ACPI Tables + for (Idx = 0; Idx < AcpiTableCount; Idx++) { + DEBUG (( + DEBUG_INFO, + "INFO: AcpiTableInfo[%d].TableGeneratorId = 0x%x\n", + Idx, + AcpiTableInfo[Idx].TableGeneratorId + )); + + // Skip FADT Table since we have already added + if (CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdFadt) == + AcpiTableInfo[Idx].TableGeneratorId) + { + continue; + } + + // Skip the Reserved table Generator ID for standard generators + if ((IS_GENERATOR_NAMESPACE_STD (AcpiTableInfo[Idx].TableGeneratorId)) && + ((CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdReserved) >= + AcpiTableInfo[Idx].TableGeneratorId) || + (CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdMax) <= + AcpiTableInfo[Idx].TableGeneratorId))) + { + DEBUG (( + DEBUG_WARN, + "WARNING: Invalid ACPI Generator table ID = 0x%x, Skipping...\n", + AcpiTableInfo[Idx].TableGeneratorId + )); + continue; + } + + Status = BuildAndInstallAcpiTable ( + TableFactoryProtocol, + CfgMgrProtocol, + AcpiTableProtocol, + &AcpiTableInfo[Idx] + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: Failed to find, build, and install ACPI Table." \ + " Status = %r\n", + Status + )); + return Status; + } + } // for + + return Status; +} + +/** Entrypoint of Dynamic Table Manager Dxe. + + The Dynamic Table Manager uses the Configuration Manager Protocol + to get the list of ACPI and SMBIOS tables to install. For each table + in the list it requests the corresponding ACPI/SMBIOS table factory for + a generator capable of building the ACPI/SMBIOS table. + If a suitable table generator is found, it invokes the generator interface + to build the table. The Dynamic Table Manager then installs the + table and invokes another generator interface to free any resources + allocated for building the table. + + @param ImageHandle + @param SystemTable + + @retval EFI_SUCCESS Success. + @retval EFI_OUT_OF_RESOURCES Memory allocation failed. + @retval EFI_NOT_FOUND Required interface/object was not found. + @retval EFI_INVALID_PARAMETER Some parameter is incorrect/invalid. +**/ +VOID +EFIAPI +AcpiTableProtocolReady ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + EFI_STATUS Status; + EDKII_CONFIGURATION_MANAGER_PROTOCOL *CfgMgrProtocol; + CM_STD_OBJ_CONFIGURATION_MANAGER_INFO *CfgMfrInfo; + EDKII_DYNAMIC_TABLE_FACTORY_PROTOCOL *TableFactoryProtocol; + + // Locate the Dynamic Table Factory + Status = gBS->LocateProtocol ( + &gEdkiiDynamicTableFactoryProtocolGuid, + NULL, + (VOID **)&TableFactoryProtocol + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: Failed to find Dynamic Table Factory protocol." \ + " Status = %r\n", + Status + )); + return; + } + + // Locate the Configuration Manager for the Platform + Status = gBS->LocateProtocol ( + &gEdkiiConfigurationManagerProtocolGuid, + NULL, + (VOID **)&CfgMgrProtocol + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: Failed to find Configuration Manager protocol. Status = %r\n", + Status + )); + return; + } + + Status = GetCgfMgrInfo (CfgMgrProtocol, &CfgMfrInfo); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: Failed to get Configuration Manager info. Status = %r\n", + Status + )); + return; + } + + DEBUG (( + DEBUG_INFO, + "INFO: Configuration Manager Version = 0x%x, OemID = %c%c%c%c%c%c\n", + CfgMfrInfo->Revision, + CfgMfrInfo->OemId[0], + CfgMfrInfo->OemId[1], + CfgMfrInfo->OemId[2], + CfgMfrInfo->OemId[3], + CfgMfrInfo->OemId[4], + CfgMfrInfo->OemId[5] + )); + + Status = ProcessAcpiTables (TableFactoryProtocol, CfgMgrProtocol); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: ACPI Table processing failure. Status = %r\n", + Status + )); + } +} diff --git a/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManagerDxe.c b/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManagerDxe.c index 26aa9b55cf..6ad2e623b2 100644 --- a/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManagerDxe.c +++ b/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManagerDxe.c @@ -2,6 +2,7 @@ Dynamic Table Manager Dxe Copyright (c) 2017 - 2019, ARM Limited. All rights reserved. + Copyright (c) 2022 - 2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: BSD-2-Clause-Patent @@ -11,10 +12,6 @@ #include #include #include -#include -#include -#include -#include // Module specific include files. #include @@ -24,1351 +21,25 @@ #include #include #include -#include -#include -/// -/// Bit definitions for acceptable ACPI table presence formats. -/// Currently only ACPI tables present in the ACPI info list and -/// already installed will count towards "Table Present" during -/// verification routine. -/// -#define ACPI_TABLE_PRESENT_INFO_LIST BIT0 -#define ACPI_TABLE_PRESENT_INSTALLED BIT1 - -/// -/// Order of ACPI table being verified during presence inspection. -/// -#define ACPI_TABLE_VERIFY_FADT 0 -#define ACPI_TABLE_VERIFY_MADT 1 -#define ACPI_TABLE_VERIFY_GTDT 2 -#define ACPI_TABLE_VERIFY_DSDT 3 -#define ACPI_TABLE_VERIFY_DBG2 4 -#define ACPI_TABLE_VERIFY_SPCR 5 -#define ACPI_TABLE_VERIFY_COUNT 6 - -/// -/// Private data structure to verify the presence of mandatory -/// or optional ACPI tables. -/// -typedef struct { - /// ESTD ID for the ACPI table of interest. - ESTD_ACPI_TABLE_ID EstdTableId; - /// Standard UINT32 ACPI signature. - UINT32 AcpiTableSignature; - /// 4 character ACPI table name (the 5th char8 is for null terminator). - CHAR8 AcpiTableName[sizeof (UINT32) + 1]; - /// Indicator on whether the ACPI table is required. - BOOLEAN IsMandatory; - /// Formats of verified presences, as defined by ACPI_TABLE_PRESENT_* - /// This field should be initialized to 0 and will be populated during - /// verification routine. - UINT16 Presence; -} ACPI_TABLE_PRESENCE_INFO; - -/// -/// We require the FADT, MADT, GTDT and the DSDT tables to boot. -/// This list also include optional ACPI tables: DBG2, SPCR. -/// -ACPI_TABLE_PRESENCE_INFO mAcpiVerifyTables[ACPI_TABLE_VERIFY_COUNT] = { - { EStdAcpiTableIdFadt, EFI_ACPI_6_2_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE, "FADT", TRUE, 0 }, - { EStdAcpiTableIdMadt, EFI_ACPI_6_2_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE, "MADT", TRUE, 0 }, - { EStdAcpiTableIdGtdt, EFI_ACPI_6_2_GENERIC_TIMER_DESCRIPTION_TABLE_SIGNATURE, "GTDT", TRUE, 0 }, - { EStdAcpiTableIdDsdt, EFI_ACPI_6_2_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE, "DSDT", TRUE, 0 }, - { EStdAcpiTableIdDbg2, EFI_ACPI_6_2_DEBUG_PORT_2_TABLE_SIGNATURE, "DBG2", FALSE, 0 }, - { EStdAcpiTableIdSpcr, EFI_ACPI_6_2_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_SIGNATURE, "SPCR", FALSE, 0 }, -}; - -/** This macro expands to a function that retrieves the ACPI Table - List from the Configuration Manager. -*/ -GET_OBJECT_LIST ( - EObjNameSpaceStandard, - EStdObjAcpiTableList, - CM_STD_OBJ_ACPI_TABLE_INFO - ) - -/** This macro expands to a function that retrieves the SMBIOS Table - List from the Configuration Manager. -*/ -GET_OBJECT_LIST ( - EObjNameSpaceStandard, - EStdObjSmbiosTableList, - CM_STD_OBJ_SMBIOS_TABLE_INFO - ) - -STATIC VOID *AcpiTableProtocolRegistration; +STATIC VOID *AcpiTableProtocolRegistration; STATIC VOID *SmbiosProtocolRegistration; -/** A helper function to build and install a single ACPI table. - - This is a helper function that invokes the Table generator interface - for building an ACPI table. It uses the AcpiTableProtocol to install the - table, then frees the resources allocated for generating it. - - @param [in] TableFactoryProtocol Pointer to the Table Factory Protocol - interface. - @param [in] CfgMgrProtocol Pointer to the Configuration Manager - Protocol Interface. - @param [in] Generator Pointer to the AcpiTable generator. - @param [in] AcpiTableProtocol Pointer to the AcpiTable protocol. - @param [in] AcpiTableInfo Pointer to the ACPI table Info. - - @retval EFI_SUCCESS Success. - @retval EFI_INVALID_PARAMETER A parameter is invalid. - @retval EFI_NOT_FOUND Required object is not found. - @retval EFI_BAD_BUFFER_SIZE Size returned by the Configuration Manager - is less than the Object size for the - requested object. -**/ -STATIC -EFI_STATUS -EFIAPI -BuildAndInstallSingleAcpiTable ( - IN CONST EDKII_DYNAMIC_TABLE_FACTORY_PROTOCOL *CONST TableFactoryProtocol, - IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, - IN CONST ACPI_TABLE_GENERATOR *CONST Generator, - IN EFI_ACPI_TABLE_PROTOCOL *AcpiTableProtocol, - IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo - ) -{ - EFI_STATUS Status; - EFI_STATUS Status1; - EFI_ACPI_DESCRIPTION_HEADER *AcpiTable; - UINTN TableHandle; - - AcpiTable = NULL; - Status = Generator->BuildAcpiTable ( - Generator, - AcpiTableInfo, - CfgMgrProtocol, - &AcpiTable - ); - if (EFI_ERROR (Status)) { - DEBUG (( - DEBUG_ERROR, - "ERROR: Failed to Build Table." \ - " TableGeneratorId = 0x%x. Status = %r\n", - AcpiTableInfo->TableGeneratorId, - Status - )); - // Free any allocated resources. - goto exit_handler; - } - - if (AcpiTable == NULL) { - Status = EFI_NOT_FOUND; - goto exit_handler; - } - - // Dump ACPI Table Header - DUMP_ACPI_TABLE_HEADER (AcpiTable); - - // Install ACPI table - Status = AcpiTableProtocol->InstallAcpiTable ( - AcpiTableProtocol, - AcpiTable, - AcpiTable->Length, - &TableHandle - ); - if (EFI_ERROR (Status)) { - DEBUG (( - DEBUG_ERROR, - "ERROR: Failed to Install ACPI Table. Status = %r\n", - Status - )); - // Free any allocated resources. - goto exit_handler; - } - - DEBUG (( - DEBUG_INFO, - "INFO: ACPI Table installed. Status = %r\n", - Status - )); - -exit_handler: - // Free any resources allocated for generating the tables. - if (Generator->FreeTableResources != NULL) { - Status1 = Generator->FreeTableResources ( - Generator, - AcpiTableInfo, - CfgMgrProtocol, - &AcpiTable - ); - if (EFI_ERROR (Status1)) { - DEBUG (( - DEBUG_ERROR, - "ERROR: Failed to Free Table Resources." \ - "TableGeneratorId = 0x%x. Status = %r\n", - AcpiTableInfo->TableGeneratorId, - Status1 - )); - } - - // Return the first error status in case of failure - if (!EFI_ERROR (Status)) { - Status = Status1; - } - } - - return Status; -} - -/** A helper function to build and install multiple ACPI tables. - - This is a helper function that invokes the Table generator interface - for building an ACPI table. It uses the AcpiTableProtocol to install the - table, then frees the resources allocated for generating it. - - @param [in] TableFactoryProtocol Pointer to the Table Factory Protocol - interface. - @param [in] CfgMgrProtocol Pointer to the Configuration Manager - Protocol Interface. - @param [in] Generator Pointer to the AcpiTable generator. - @param [in] AcpiTableProtocol Pointer to the AcpiTable protocol. - @param [in] AcpiTableInfo Pointer to the ACPI table Info. - - @retval EFI_SUCCESS Success. - @retval EFI_INVALID_PARAMETER A parameter is invalid. - @retval EFI_NOT_FOUND Required object is not found. - @retval EFI_BAD_BUFFER_SIZE Size returned by the Configuration Manager - is less than the Object size for the - requested object. -**/ -STATIC -EFI_STATUS -EFIAPI -BuildAndInstallMultipleAcpiTable ( - IN CONST EDKII_DYNAMIC_TABLE_FACTORY_PROTOCOL *CONST TableFactoryProtocol, - IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, - IN CONST ACPI_TABLE_GENERATOR *CONST Generator, - IN EFI_ACPI_TABLE_PROTOCOL *AcpiTableProtocol, - IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo - ) -{ - EFI_STATUS Status; - EFI_STATUS Status1; - EFI_ACPI_DESCRIPTION_HEADER **AcpiTable; - UINTN TableCount; - UINTN TableHandle; - UINTN Index; - - AcpiTable = NULL; - TableCount = 0; - Status = Generator->BuildAcpiTableEx ( - Generator, - AcpiTableInfo, - CfgMgrProtocol, - &AcpiTable, - &TableCount - ); - if (EFI_ERROR (Status)) { - DEBUG (( - DEBUG_ERROR, - "ERROR: Failed to Build Table." \ - " TableGeneratorId = 0x%x. Status = %r\n", - AcpiTableInfo->TableGeneratorId, - Status - )); - // Free any allocated resources. - goto exit_handler; - } - - if ((AcpiTable == NULL) || (TableCount == 0)) { - Status = EFI_NOT_FOUND; - goto exit_handler; - } - - for (Index = 0; Index < TableCount; Index++) { - // Dump ACPI Table Header - DUMP_ACPI_TABLE_HEADER (AcpiTable[Index]); - // Install ACPI table - Status = AcpiTableProtocol->InstallAcpiTable ( - AcpiTableProtocol, - AcpiTable[Index], - AcpiTable[Index]->Length, - &TableHandle - ); - if (EFI_ERROR (Status)) { - DEBUG (( - DEBUG_ERROR, - "ERROR: Failed to Install ACPI Table. Status = %r\n", - Status - )); - // Free any allocated resources. - goto exit_handler; - } - - DEBUG (( - DEBUG_INFO, - "INFO: ACPI Table installed. Status = %r\n", - Status - )); - } - -exit_handler: - // Free any resources allocated for generating the tables. - if (Generator->FreeTableResourcesEx != NULL) { - Status1 = Generator->FreeTableResourcesEx ( - Generator, - AcpiTableInfo, - CfgMgrProtocol, - &AcpiTable, - TableCount - ); - if (EFI_ERROR (Status1)) { - DEBUG (( - DEBUG_ERROR, - "ERROR: Failed to Free Table Resources." \ - "TableGeneratorId = 0x%x. Status = %r\n", - AcpiTableInfo->TableGeneratorId, - Status1 - )); - } - - // Return the first error status in case of failure - if (!EFI_ERROR (Status)) { - Status = Status1; - } - } - - return Status; -} - -/** A helper function to invoke a Table generator - - This is a helper function that invokes the Table generator interface - for building an ACPI table. It uses the AcpiTableProtocol to install the - table, then frees the resources allocated for generating it. - - @param [in] TableFactoryProtocol Pointer to the Table Factory Protocol - interface. - @param [in] CfgMgrProtocol Pointer to the Configuration Manager - Protocol Interface. - @param [in] AcpiTableProtocol Pointer to the AcpiTable protocol. - @param [in] AcpiTableInfo Pointer to the ACPI table Info. - - @retval EFI_SUCCESS Success. - @retval EFI_INVALID_PARAMETER A parameter is invalid. - @retval EFI_NOT_FOUND Required object is not found. - @retval EFI_BAD_BUFFER_SIZE Size returned by the Configuration Manager - is less than the Object size for the - requested object. -**/ -STATIC -EFI_STATUS -EFIAPI -BuildAndInstallAcpiTable ( - IN CONST EDKII_DYNAMIC_TABLE_FACTORY_PROTOCOL *CONST TableFactoryProtocol, - IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, - IN EFI_ACPI_TABLE_PROTOCOL *AcpiTableProtocol, - IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo - ) -{ - EFI_STATUS Status; - CONST ACPI_TABLE_GENERATOR *Generator; - - ASSERT (TableFactoryProtocol != NULL); - ASSERT (CfgMgrProtocol != NULL); - ASSERT (AcpiTableProtocol != NULL); - ASSERT (AcpiTableInfo != NULL); - - DEBUG (( - DEBUG_INFO, - "INFO: EStdObjAcpiTableList: Address = 0x%p," \ - " TableGeneratorId = 0x%x\n", - AcpiTableInfo, - AcpiTableInfo->TableGeneratorId - )); - - Generator = NULL; - Status = TableFactoryProtocol->GetAcpiTableGenerator ( - TableFactoryProtocol, - AcpiTableInfo->TableGeneratorId, - &Generator - ); - if (EFI_ERROR (Status)) { - DEBUG (( - DEBUG_ERROR, - "ERROR: Table Generator not found." \ - " TableGeneratorId = 0x%x. Status = %r\n", - AcpiTableInfo->TableGeneratorId, - Status - )); - return Status; - } - - if (Generator == NULL) { - return EFI_NOT_FOUND; - } - - DEBUG (( - DEBUG_INFO, - "INFO: Generator found : %s\n", - Generator->Description - )); - - if (Generator->BuildAcpiTableEx != NULL) { - Status = BuildAndInstallMultipleAcpiTable ( - TableFactoryProtocol, - CfgMgrProtocol, - Generator, - AcpiTableProtocol, - AcpiTableInfo - ); - if (EFI_ERROR (Status)) { - DEBUG (( - DEBUG_ERROR, - "ERROR: Failed to find build and install ACPI Table." \ - " Status = %r\n", - Status - )); - } - } else if (Generator->BuildAcpiTable != NULL) { - Status = BuildAndInstallSingleAcpiTable ( - TableFactoryProtocol, - CfgMgrProtocol, - Generator, - AcpiTableProtocol, - AcpiTableInfo - ); - if (EFI_ERROR (Status)) { - DEBUG (( - DEBUG_ERROR, - "ERROR: Failed to find build and install ACPI Table." \ - " Status = %r\n", - Status - )); - } - } else { - Status = EFI_INVALID_PARAMETER; - DEBUG (( - DEBUG_ERROR, - "ERROR: Table Generator does not implement the" \ - " ACPI_TABLE_GENERATOR_BUILD_TABLE interface." \ - " TableGeneratorId = 0x%x. Status = %r\n", - AcpiTableInfo->TableGeneratorId, - Status - )); - } - - return Status; -} - -/** The function checks if the Configuration Manager has provided the - mandatory ACPI tables for installation. - - @param [in] AcpiTableInfo Pointer to the ACPI Table Info list. - @param [in] AcpiTableCount Count of ACPI Table Info. - - @retval EFI_SUCCESS Success. - @retval EFI_NOT_FOUND If mandatory table is not found. - @retval EFI_ALREADY_STARTED If mandatory table found in AcpiTableInfo is already installed. -**/ -STATIC -EFI_STATUS -EFIAPI -VerifyMandatoryTablesArePresent ( - IN CONST CM_STD_OBJ_ACPI_TABLE_INFO *CONST AcpiTableInfo, - IN UINT32 AcpiTableCount - ) -{ - EFI_STATUS Status; - UINTN Handle; - UINTN Index; - UINTN InstalledTableIndex; - EFI_ACPI_DESCRIPTION_HEADER *DescHeader; - EFI_ACPI_TABLE_VERSION Version; - EFI_ACPI_SDT_PROTOCOL *AcpiSdt; - - ASSERT (AcpiTableInfo != NULL); - - Status = EFI_SUCCESS; - - // Check against the statically initialized ACPI tables to see if they are in ACPI info list - while (AcpiTableCount-- != 0) { - for (Index = 0; Index < ACPI_TABLE_VERIFY_COUNT; Index++) { - if (AcpiTableInfo[AcpiTableCount].AcpiTableSignature == mAcpiVerifyTables[Index].AcpiTableSignature) { - mAcpiVerifyTables[Index].Presence |= ACPI_TABLE_PRESENT_INFO_LIST; - // Found this table, skip the rest. - break; - } - } - } - - // They also might be published already, so we can search from there - if (FeaturePcdGet (PcdInstallAcpiSdtProtocol)) { - AcpiSdt = NULL; - Status = gBS->LocateProtocol (&gEfiAcpiSdtProtocolGuid, NULL, (VOID **)&AcpiSdt); - - if (EFI_ERROR (Status) || (AcpiSdt == NULL)) { - DEBUG ((DEBUG_ERROR, "ERROR: Failed to locate ACPI SDT protocol (0x%p) - %r\n", AcpiSdt, Status)); - return Status; - } - - for (Index = 0; Index < ACPI_TABLE_VERIFY_COUNT; Index++) { - Handle = 0; - InstalledTableIndex = 0; - do { - Status = AcpiSdt->GetAcpiTable (InstalledTableIndex, (EFI_ACPI_SDT_HEADER **)&DescHeader, &Version, &Handle); - if (EFI_ERROR (Status)) { - break; - } - - InstalledTableIndex++; - } while (DescHeader->Signature != mAcpiVerifyTables[Index].AcpiTableSignature); - - if (!EFI_ERROR (Status)) { - mAcpiVerifyTables[Index].Presence |= ACPI_TABLE_PRESENT_INSTALLED; - } - } - } - - // Reset the return Status value to EFI_SUCCESS. We do not fully care if the table look up has failed. - Status = EFI_SUCCESS; - for (Index = 0; Index < ACPI_TABLE_VERIFY_COUNT; Index++) { - if (mAcpiVerifyTables[Index].Presence == 0) { - if (mAcpiVerifyTables[Index].IsMandatory) { - DEBUG ((DEBUG_ERROR, "ERROR: %a Table not found.\n", mAcpiVerifyTables[Index].AcpiTableName)); - Status = EFI_NOT_FOUND; - } else { - DEBUG ((DEBUG_WARN, "WARNING: %a Table not found.\n", mAcpiVerifyTables[Index].AcpiTableName)); - } - } else if (mAcpiVerifyTables[Index].Presence == - (ACPI_TABLE_PRESENT_INFO_LIST | ACPI_TABLE_PRESENT_INSTALLED)) - { - DEBUG ((DEBUG_ERROR, "ERROR: %a Table found while already published.\n", mAcpiVerifyTables[Index].AcpiTableName)); - Status = EFI_ALREADY_STARTED; - } - } - - return Status; -} - -/** A helper function to build and install an SMBIOS table. - - This is a helper function that invokes the Table generator interface - for building an SMBIOS table. It uses the SmbiosProtocol to install the - table, then frees the resources allocated for generating it. - - @param [in] TableFactoryProtocol Pointer to the Table Factory Protocol - interface. - @param [in] CfgMgrProtocol Pointer to the Configuration Manager - Protocol Interface. - @param [in] SmbiosProtocol Pointer to the SMBIOS protocol. - @param [in] SmbiosTableInfo Pointer to the SMBIOS table Info. - - @retval EFI_SUCCESS Success. - @retval EFI_INVALID_PARAMETER A parameter is invalid. - @retval EFI_NOT_FOUND Required object is not found. - @retval EFI_BAD_BUFFER_SIZE Size returned by the Configuration Manager - is less than the Object size for the - requested object. -**/ -STATIC -EFI_STATUS -EFIAPI -BuildAndInstallSingleSmbiosTable ( - IN CONST EDKII_DYNAMIC_TABLE_FACTORY_PROTOCOL *CONST TableFactoryProtocol, - IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, - IN CONST SMBIOS_TABLE_GENERATOR *CONST Generator, - IN EFI_SMBIOS_PROTOCOL *SmbiosProtocol, - IN CM_STD_OBJ_SMBIOS_TABLE_INFO *CONST SmbiosTableInfo - ) -{ - EFI_STATUS Status; - EFI_STATUS Status1; - SMBIOS_STRUCTURE *SmbiosTable; - CM_OBJECT_TOKEN CmObjToken; - EFI_SMBIOS_HANDLE TableHandle; - - SmbiosTable = NULL; - Status = Generator->BuildSmbiosTable ( - Generator, - TableFactoryProtocol, - SmbiosTableInfo, - CfgMgrProtocol, - &SmbiosTable, - &CmObjToken - ); - if (EFI_ERROR (Status)) { - DEBUG (( - DEBUG_ERROR, - "ERROR: Failed to Build Table." \ - " TableGeneratorId = 0x%x. Status = %r\n", - SmbiosTableInfo->TableGeneratorId, - Status - )); - // Free any allocated resources. - goto exit_handler; - } - - if (SmbiosTable == NULL) { - Status = EFI_NOT_FOUND; - goto exit_handler; - } - - TableHandle = SMBIOS_HANDLE_PI_RESERVED; - // Install SMBIOS table - Status = SmbiosProtocol->Add ( - SmbiosProtocol, - NULL, - &TableHandle, - SmbiosTable - ); - if (EFI_ERROR (Status)) { - DEBUG (( - DEBUG_ERROR, - "ERROR: Failed to Install SMBIOS Table. Status = %r\n", - Status - )); - // Free any allocated resources. - goto exit_handler; - } - - Status = TableFactoryProtocol->AddSmbiosHandle ( - SmbiosProtocol, - &TableHandle, - CmObjToken, - SmbiosTableInfo->TableGeneratorId - ); - if (EFI_ERROR (Status)) { - DEBUG (( - DEBUG_ERROR, - "ERROR: Failed to Add SMBIOS Handle. Status = %r\n", - Status - )); - // Free any allocated resources. - goto exit_handler; - } - - DEBUG (( - DEBUG_INFO, - "INFO: SMBIOS Table installed. Status = %r\n", - Status - )); - -exit_handler: - // Free any resources allocated for generating the tables. - if (Generator->FreeTableResources != NULL) { - Status1 = Generator->FreeTableResources ( - Generator, - TableFactoryProtocol, - SmbiosTableInfo, - CfgMgrProtocol, - &SmbiosTable - ); - if (EFI_ERROR (Status1)) { - DEBUG (( - DEBUG_ERROR, - "ERROR: Failed to Free Table Resources." \ - "TableGeneratorId = 0x%x. Status = %r\n", - SmbiosTableInfo->TableGeneratorId, - Status1 - )); - } - - // Return the first error status in case of failure - if (!EFI_ERROR (Status)) { - Status = Status1; - } - } - - return Status; -} - -/** A helper function to build and install multiple SMBIOS tables. - - This is a helper function that invokes the Table generator interface - for building SMBIOS tables. It uses the SmbiosProtocol to install the - tables, then frees the resources allocated for generating it. - - @param [in] TableFactoryProtocol Pointer to the Table Factory Protocol - interface. - @param [in] CfgMgrProtocol Pointer to the Configuration Manager - Protocol Interface. - @param [in] Generator Pointer to the SmbiosTable generator. - @param [in] SmbiosProtocol Pointer to the Smbios protocol. - @param [in] AcpiTableInfo Pointer to the SMBIOS table Info. - - @retval EFI_SUCCESS Success. - @retval EFI_INVALID_PARAMETER A parameter is invalid. - @retval EFI_NOT_FOUND Required object is not found. - @retval EFI_BAD_BUFFER_SIZE Size returned by the Configuration Manager - is less than the Object size for the - requested object. -**/ -STATIC -EFI_STATUS -EFIAPI -BuildAndInstallMultipleSmbiosTables ( - IN CONST EDKII_DYNAMIC_TABLE_FACTORY_PROTOCOL *CONST TableFactoryProtocol, - IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, - IN CONST SMBIOS_TABLE_GENERATOR *CONST Generator, - IN EFI_SMBIOS_PROTOCOL *SmbiosProtocol, - IN CM_STD_OBJ_SMBIOS_TABLE_INFO *CONST SmbiosTableInfo - ) -{ - EFI_STATUS Status; - EFI_STATUS Status1; - SMBIOS_STRUCTURE **SmbiosTable; - CM_OBJECT_TOKEN *CmObjToken; - EFI_SMBIOS_HANDLE TableHandle; - UINTN TableCount; - UINTN Index; - - TableCount = 0; - Status = Generator->BuildSmbiosTableEx ( - Generator, - TableFactoryProtocol, - SmbiosTableInfo, - CfgMgrProtocol, - &SmbiosTable, - &CmObjToken, - &TableCount - ); - if (EFI_ERROR (Status)) { - DEBUG (( - DEBUG_ERROR, - "ERROR: Failed to Build Table." \ - " TableGeneratorId = 0x%x. Status = %r\n", - SmbiosTableInfo->TableGeneratorId, - Status - )); - // Free any allocated resources. - goto exit_handler; - } - - if ((SmbiosTable == NULL) || (TableCount == 0)) { - Status = EFI_NOT_FOUND; - DEBUG (( - DEBUG_ERROR, - "%a: TableCount %u SmbiosTable %p \n", - __FUNCTION__, - TableCount, - SmbiosTable - )); - goto exit_handler; - } - - for (Index = 0; Index < TableCount; Index++) { - TableHandle = SMBIOS_HANDLE_PI_RESERVED; - - // Install SMBIOS table - Status = SmbiosProtocol->Add ( - SmbiosProtocol, - NULL, - &TableHandle, - SmbiosTable[Index] - ); - if (EFI_ERROR (Status)) { - DEBUG (( - DEBUG_ERROR, - "ERROR: Failed to Install SMBIOS Table. Status = %r\n", - Status - )); - // Free any allocated resources. - goto exit_handler; - } - - Status = TableFactoryProtocol->AddSmbiosHandle ( - SmbiosProtocol, - &TableHandle, - CmObjToken[Index], - SmbiosTableInfo->TableGeneratorId - ); - if (EFI_ERROR (Status)) { - DEBUG (( - DEBUG_ERROR, - "ERROR: Failed to Add SMBIOS Handle. Status = %r\n", - Status - )); - // Free any allocated resources. - goto exit_handler; - } - - DEBUG (( - DEBUG_INFO, - "INFO: SMBIOS Table installed. Status = %r\n", - Status - )); - } - -exit_handler: - // Free any resources allocated for generating the tables. - if (Generator->FreeTableResourcesEx != NULL) { - Status1 = Generator->FreeTableResourcesEx ( - Generator, - TableFactoryProtocol, - SmbiosTableInfo, - CfgMgrProtocol, - &SmbiosTable, - &CmObjToken, - TableCount - ); - if (EFI_ERROR (Status1)) { - DEBUG (( - DEBUG_ERROR, - "ERROR: Failed to Free Table Resources." \ - "TableGeneratorId = 0x%x. Status = %r\n", - SmbiosTableInfo->TableGeneratorId, - Status1 - )); - } - - // Return the first error status in case of failure - if (!EFI_ERROR (Status)) { - Status = Status1; - } - } - - DEBUG ((DEBUG_ERROR, "%a: Returning %r\n", __FUNCTION__, Status)); - return Status; -} - -/** A helper function to invoke a Table generator - - This is a helper function that invokes the Table generator interface - for building an SMBIOS table. It uses the SmbiosProtocol to install the - table, then frees the resources allocated for generating it. - - @param [in] TableFactoryProtocol Pointer to the Table Factory Protocol - interface. - @param [in] CfgMgrProtocol Pointer to the Configuration Manager - Protocol Interface. - @param [in] SmbiosProtocol Pointer to the SMBIOS protocol. - @param [in] SmbiosTableInfo Pointer to the SMBIOS table Info. - - @retval EFI_SUCCESS Success. - @retval EFI_INVALID_PARAMETER A parameter is invalid. - @retval EFI_NOT_FOUND Required object is not found. - @retval EFI_BAD_BUFFER_SIZE Size returned by the Configuration Manager - is less than the Object size for the - requested object. -**/ -EFI_STATUS -EFIAPI -BuildAndInstallSmbiosTable ( - IN CONST EDKII_DYNAMIC_TABLE_FACTORY_PROTOCOL *CONST TableFactoryProtocol, - IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, - IN EFI_SMBIOS_PROTOCOL *SmbiosProtocol, - IN CM_STD_OBJ_SMBIOS_TABLE_INFO *CONST SmbiosTableInfo - ) -{ - EFI_STATUS Status; - CONST SMBIOS_TABLE_GENERATOR *Generator; - - ASSERT (TableFactoryProtocol != NULL); - ASSERT (CfgMgrProtocol != NULL); - ASSERT (SmbiosProtocol != NULL); - ASSERT (SmbiosTableInfo != NULL); - - DEBUG (( - DEBUG_INFO, - "INFO: EStdObjSmbiosTableList: Address = 0x%p," \ - " TableGeneratorId = 0x%x\n", - SmbiosTableInfo, - SmbiosTableInfo->TableGeneratorId - )); - - Generator = NULL; - Status = TableFactoryProtocol->GetSmbiosTableGenerator ( - TableFactoryProtocol, - SmbiosTableInfo->TableGeneratorId, - &Generator - ); - if (EFI_ERROR (Status)) { - DEBUG (( - DEBUG_ERROR, - "ERROR: Table Generator not found." \ - " TableGeneratorId = 0x%x. Status = %r\n", - SmbiosTableInfo->TableGeneratorId, - Status - )); - return Status; - } - - if (Generator == NULL) { - return EFI_NOT_FOUND; - } - - DEBUG (( - DEBUG_INFO, - "INFO: Generator found : %s\n", - Generator->Description - )); - - if (Generator->BuildSmbiosTableEx != NULL) { - Status = BuildAndInstallMultipleSmbiosTables ( - TableFactoryProtocol, - CfgMgrProtocol, - Generator, - SmbiosProtocol, - SmbiosTableInfo - ); - if (EFI_ERROR (Status)) { - DEBUG (( - DEBUG_ERROR, - "ERROR: Failed to find build and install SMBIOS Tables." \ - " Status = %r\n", - Status - )); - } - } else if (Generator->BuildSmbiosTable != NULL) { - Status = BuildAndInstallSingleSmbiosTable ( - TableFactoryProtocol, - CfgMgrProtocol, - Generator, - SmbiosProtocol, - SmbiosTableInfo - ); - if (EFI_ERROR (Status)) { - DEBUG (( - DEBUG_ERROR, - "ERROR: Failed to find build and install SMBIOS Table." \ - " Status = %r\n", - Status - )); - } - } else { - Status = EFI_INVALID_PARAMETER; - DEBUG (( - DEBUG_ERROR, - "ERROR: Table Generator does not implement the" \ - "SMBIOS_TABLE_GENERATOR_BUILD_TABLE interface." \ - " TableGeneratorId = 0x%x. Status = %r\n", - SmbiosTableInfo->TableGeneratorId, - Status - )); - } - - DEBUG ((DEBUG_ERROR, "%a: Returning %r\n", __FUNCTION__, Status)); - return Status; -} - -/** Generate and install SMBIOS tables. - - The function gathers the information necessary for installing the - SMBIOS tables from the Configuration Manager, invokes the generators - and installs them (via BuildAndInstallAcpiTable). - - @param [in] TableFactoryProtocol Pointer to the Table Factory Protocol - interface. - @param [in] CfgMgrProtocol Pointer to the Configuration Manager - Protocol Interface. - - @retval EFI_SUCCESS Success. - @retval EFI_NOT_FOUND If a mandatory table or a generator is not found. -**/ -STATIC -EFI_STATUS -EFIAPI -ProcessSmbiosTables ( - IN CONST EDKII_DYNAMIC_TABLE_FACTORY_PROTOCOL *CONST TableFactoryProtocol, - IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol - ) -{ - EFI_STATUS Status; - EFI_SMBIOS_PROTOCOL *SmbiosProtocol; - CM_STD_OBJ_SMBIOS_TABLE_INFO *SmbiosTableInfo; - UINT32 SmbiosTableCount; - - Status = gBS->LocateProtocol (&gEfiSmbiosProtocolGuid, NULL, (VOID **)&SmbiosProtocol); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "Could not locate SMBIOS protocol. %r\n", Status)); - return Status; - } - - Status = GetEStdObjSmbiosTableList ( - CfgMgrProtocol, - CM_NULL_TOKEN, - &SmbiosTableInfo, - &SmbiosTableCount - ); - if (EFI_ERROR (Status)) { - DEBUG (( - DEBUG_ERROR, - "ERROR: Failed to get SMBIOS Table List. Status = %r\n", - Status - )); - return Status; - } - - if (SmbiosTableCount == 0) { - DEBUG (( - DEBUG_ERROR, - "ERROR: EStdObjSmbiosTableList: SmbiosTableCount = %d\n", - SmbiosTableCount - )); - return EFI_NOT_FOUND; - } - - DEBUG (( - DEBUG_INFO, - "INFO: EStdObjSmbiosTableList: SmbiosTableCount = %d\n", - SmbiosTableCount - )); - - InitSmbiosTableDispatcher (SmbiosTableInfo, SmbiosTableCount); - - Status = DispatchSmbiosTables ( - TableFactoryProtocol, - CfgMgrProtocol, - SmbiosProtocol, - SmbiosTableInfo, - SmbiosTableCount - ); - if (EFI_ERROR (Status)) { - DEBUG (( - DEBUG_ERROR, - "ERROR: Failed to install SMBIOS Tables.Status = %r\n", - Status - )); - } - - return Status; -} - -/** Generate and install ACPI tables. - - The function gathers the information necessary for installing the - ACPI tables from the Configuration Manager, invokes the generators - and installs them (via BuildAndInstallAcpiTable). - - @param [in] TableFactoryProtocol Pointer to the Table Factory Protocol - interface. - @param [in] CfgMgrProtocol Pointer to the Configuration Manager - Protocol Interface. - - @retval EFI_SUCCESS Success. - @retval EFI_NOT_FOUND If a mandatory table or a generator is not found. - @retval EFI_ALREADY_STARTED If mandatory table found in AcpiTableInfo is already installed. -**/ -STATIC -EFI_STATUS -EFIAPI -ProcessAcpiTables ( - IN CONST EDKII_DYNAMIC_TABLE_FACTORY_PROTOCOL *CONST TableFactoryProtocol, - IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol - ) -{ - EFI_STATUS Status; - EFI_ACPI_TABLE_PROTOCOL *AcpiTableProtocol; - CM_STD_OBJ_ACPI_TABLE_INFO *AcpiTableInfo; - UINT32 AcpiTableCount; - UINT32 Idx; - - ASSERT (TableFactoryProtocol != NULL); - ASSERT (CfgMgrProtocol != NULL); - - // Find the AcpiTable protocol - Status = gBS->LocateProtocol ( - &gEfiAcpiTableProtocolGuid, - NULL, - (VOID **)&AcpiTableProtocol - ); - if (EFI_ERROR (Status)) { - DEBUG (( - DEBUG_ERROR, - "ERROR: Failed to find AcpiTable protocol. Status = %r\n", - Status - )); - return Status; - } - - Status = GetEStdObjAcpiTableList ( - CfgMgrProtocol, - CM_NULL_TOKEN, - &AcpiTableInfo, - &AcpiTableCount - ); - if (EFI_ERROR (Status)) { - DEBUG (( - DEBUG_ERROR, - "ERROR: Failed to get ACPI Table List. Status = %r\n", - Status - )); - return Status; - } - - if (0 == AcpiTableCount) { - DEBUG (( - DEBUG_ERROR, - "ERROR: EStdObjAcpiTableList: AcpiTableCount = %d\n", - AcpiTableCount - )); - return EFI_NOT_FOUND; - } - - DEBUG (( - DEBUG_INFO, - "INFO: EStdObjAcpiTableList: AcpiTableCount = %d\n", - AcpiTableCount - )); - - // Check if mandatory ACPI tables are present. - Status = VerifyMandatoryTablesArePresent ( - AcpiTableInfo, - AcpiTableCount - ); - if (EFI_ERROR (Status)) { - DEBUG (( - DEBUG_ERROR, - "ERROR: Failed to verify mandatory ACPI Table(s) presence." - " Status = %r\n", - Status - )); - return Status; - } - - // Add the FADT Table first. - if ((mAcpiVerifyTables[ACPI_TABLE_VERIFY_FADT].Presence & ACPI_TABLE_PRESENT_INSTALLED) == 0) { - // FADT is not yet installed - for (Idx = 0; Idx < AcpiTableCount; Idx++) { - if (CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdFadt) == - AcpiTableInfo[Idx].TableGeneratorId) - { - Status = BuildAndInstallAcpiTable ( - TableFactoryProtocol, - CfgMgrProtocol, - AcpiTableProtocol, - &AcpiTableInfo[Idx] - ); - if (EFI_ERROR (Status)) { - DEBUG (( - DEBUG_ERROR, - "ERROR: Failed to find build and install ACPI FADT Table." \ - " Status = %r\n", - Status - )); - return Status; - } - - break; - } - } // for - } - - // Add remaining ACPI Tables - for (Idx = 0; Idx < AcpiTableCount; Idx++) { - DEBUG (( - DEBUG_INFO, - "INFO: AcpiTableInfo[%d].TableGeneratorId = 0x%x\n", - Idx, - AcpiTableInfo[Idx].TableGeneratorId - )); - - // Skip FADT Table since we have already added - if (CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdFadt) == - AcpiTableInfo[Idx].TableGeneratorId) - { - continue; - } - - // Skip the Reserved table Generator ID for standard generators - if ((IS_GENERATOR_NAMESPACE_STD (AcpiTableInfo[Idx].TableGeneratorId)) && - ((CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdReserved) >= - AcpiTableInfo[Idx].TableGeneratorId) || - (CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdMax) <= - AcpiTableInfo[Idx].TableGeneratorId))) - { - DEBUG (( - DEBUG_WARN, - "WARNING: Invalid ACPI Generator table ID = 0x%x, Skipping...\n", - AcpiTableInfo[Idx].TableGeneratorId - )); - continue; - } - - Status = BuildAndInstallAcpiTable ( - TableFactoryProtocol, - CfgMgrProtocol, - AcpiTableProtocol, - &AcpiTableInfo[Idx] - ); - if (EFI_ERROR (Status)) { - DEBUG (( - DEBUG_ERROR, - "ERROR: Failed to find, build, and install ACPI Table." \ - " Status = %r\n", - Status - )); - return Status; - } - } // for - - return Status; -} - -/** Callback function for ACPI Protocol . - - Callback function for ACPI protocol that installs ACPI tables - - @param Event - @param Context - - @retval None -**/ -STATIC +extern VOID -AcpiTableProtocolReady ( +EFIAPI +SmbiosProtocolReady ( IN EFI_EVENT Event, IN VOID *Context - ) -{ - EFI_STATUS Status; - EDKII_CONFIGURATION_MANAGER_PROTOCOL *CfgMgrProtocol; - CM_STD_OBJ_CONFIGURATION_MANAGER_INFO *CfgMfrInfo; - EDKII_DYNAMIC_TABLE_FACTORY_PROTOCOL *TableFactoryProtocol; - - // Locate the Dynamic Table Factory - Status = gBS->LocateProtocol ( - &gEdkiiDynamicTableFactoryProtocolGuid, - NULL, - (VOID **)&TableFactoryProtocol - ); - if (EFI_ERROR (Status)) { - DEBUG (( - DEBUG_ERROR, - "ERROR: Failed to find Dynamic Table Factory protocol." \ - " Status = %r\n", - Status - )); - return; - } + ); - // Locate the Configuration Manager for the Platform - Status = gBS->LocateProtocol ( - &gEdkiiConfigurationManagerProtocolGuid, - NULL, - (VOID **)&CfgMgrProtocol - ); - if (EFI_ERROR (Status)) { - DEBUG (( - DEBUG_ERROR, - "ERROR: Failed to find Configuration Manager protocol. Status = %r\n", - Status - )); - return; - } - - Status = GetCgfMgrInfo (CfgMgrProtocol, &CfgMfrInfo); - if (EFI_ERROR (Status)) { - DEBUG (( - DEBUG_ERROR, - "ERROR: Failed to get Configuration Manager info. Status = %r\n", - Status - )); - return; - } - - DEBUG (( - DEBUG_INFO, - "INFO: Configuration Manager Version = 0x%x, OemID = %c%c%c%c%c%c\n", - CfgMfrInfo->Revision, - CfgMfrInfo->OemId[0], - CfgMfrInfo->OemId[1], - CfgMfrInfo->OemId[2], - CfgMfrInfo->OemId[3], - CfgMfrInfo->OemId[4], - CfgMfrInfo->OemId[5] - )); - - Status = ProcessAcpiTables (TableFactoryProtocol, CfgMgrProtocol); - if (EFI_ERROR (Status)) { - DEBUG (( - DEBUG_ERROR, - "ERROR: ACPI Table processing failure. Status = %r\n", - Status - )); - } -} - -/** Callback function for SMBIOS Protocol . - - Callback function for SMBIOS protocol that installs SMBIOS tables - that use the DynamicTables Package. - - @param Event - @param Context - - @retval None -**/ -STATIC +extern VOID -SmbiosProtocolReady ( +EFIAPI +AcpiTableProtocolReady ( IN EFI_EVENT Event, IN VOID *Context - ) -{ - EFI_STATUS Status; - EDKII_CONFIGURATION_MANAGER_PROTOCOL *CfgMgrProtocol; - CM_STD_OBJ_CONFIGURATION_MANAGER_INFO *CfgMfrInfo; - EDKII_DYNAMIC_TABLE_FACTORY_PROTOCOL *TableFactoryProtocol; - - // Locate the Dynamic Table Factory - Status = gBS->LocateProtocol ( - &gEdkiiDynamicTableFactoryProtocolGuid, - NULL, - (VOID **)&TableFactoryProtocol - ); - if (EFI_ERROR (Status)) { - DEBUG (( - DEBUG_ERROR, - "ERROR: Failed to find Dynamic Table Factory protocol." \ - " Status = %r\n", - Status - )); - return; - } - - // Locate the Configuration Manager for the Platform - Status = gBS->LocateProtocol ( - &gEdkiiConfigurationManagerProtocolGuid, - NULL, - (VOID **)&CfgMgrProtocol - ); - if (EFI_ERROR (Status)) { - DEBUG (( - DEBUG_ERROR, - "ERROR: Failed to find Configuration Manager protocol. Status = %r\n", - Status - )); - return; - } - - Status = GetCgfMgrInfo (CfgMgrProtocol, &CfgMfrInfo); - if (EFI_ERROR (Status)) { - DEBUG (( - DEBUG_ERROR, - "ERROR: Failed to get Configuration Manager info. Status = %r\n", - Status - )); - return; - } - - DEBUG (( - DEBUG_INFO, - "INFO: Configuration Manager Version = 0x%x, OemID = %c%c%c%c%c%c\n", - CfgMfrInfo->Revision, - CfgMfrInfo->OemId[0], - CfgMfrInfo->OemId[1], - CfgMfrInfo->OemId[2], - CfgMfrInfo->OemId[3], - CfgMfrInfo->OemId[4], - CfgMfrInfo->OemId[5] - )); - - Status = ProcessSmbiosTables (TableFactoryProtocol, CfgMgrProtocol); - if (EFI_ERROR (Status)) { - DEBUG (( - DEBUG_ERROR, - "ERROR: SMBIOS Table processing failure. Status = %r\n", - Status - )); - } -} + ); /** Entrypoint of Dynamic Table Manager Dxe. @@ -1396,9 +67,8 @@ DynamicTableManagerDxeInitialize ( IN EFI_SYSTEM_TABLE *SystemTable ) { - EFI_STATUS Status; - EFI_EVENT AcpiEvent; - EFI_EVENT SmbiosEvent; + EFI_EVENT AcpiEvent; + EFI_EVENT SmbiosEvent; AcpiEvent = EfiCreateProtocolNotifyEvent ( &gEfiAcpiTableProtocolGuid, @@ -1425,5 +95,5 @@ DynamicTableManagerDxeInitialize ( return EFI_OUT_OF_RESOURCES; } - return Status; + return EFI_SUCCESS; } diff --git a/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManagerDxe.inf b/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManagerDxe.inf index 3beab7420a..93fde9f44f 100644 --- a/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManagerDxe.inf +++ b/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/DynamicTableManagerDxe.inf @@ -24,6 +24,8 @@ DynamicTableManagerDxe.c SmbiosTableDispatcher.c SmbiosTableDispatcher.h + AcpiTableBuilder.c + SmbiosTableBuilder.c [Packages] MdePkg/MdePkg.dec diff --git a/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/SmbiosTableBuilder.c b/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/SmbiosTableBuilder.c new file mode 100644 index 0000000000..bfddaac3aa --- /dev/null +++ b/DynamicTablesPkg/Drivers/DynamicTableManagerDxe/SmbiosTableBuilder.c @@ -0,0 +1,606 @@ +/** @file + Dynamic Table Manager Dxe + + Copyright (c) 2017 - 2019, ARM Limited. All rights reserved. + Copyright (c) 2022 - 2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved. + + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include +#include +#include +#include + +// Module specific include files. +#include +#include +#include +#include +#include +#include +#include +#include + +/** This macro expands to a function that retrieves the SMBIOS Table + List from the Configuration Manager. +*/ +GET_OBJECT_LIST ( + EObjNameSpaceStandard, + EStdObjSmbiosTableList, + CM_STD_OBJ_SMBIOS_TABLE_INFO + ) + +/** A helper function to build and install an SMBIOS table. + + This is a helper function that invokes the Table generator interface + for building an SMBIOS table. It uses the SmbiosProtocol to install the + table, then frees the resources allocated for generating it. + + @param [in] TableFactoryProtocol Pointer to the Table Factory Protocol + interface. + @param [in] CfgMgrProtocol Pointer to the Configuration Manager + Protocol Interface. + @param [in] SmbiosProtocol Pointer to the SMBIOS protocol. + @param [in] SmbiosTableInfo Pointer to the SMBIOS table Info. + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER A parameter is invalid. + @retval EFI_NOT_FOUND Required object is not found. + @retval EFI_BAD_BUFFER_SIZE Size returned by the Configuration Manager + is less than the Object size for the + requested object. +**/ +STATIC +EFI_STATUS +EFIAPI +BuildAndInstallSingleSmbiosTable ( + IN CONST EDKII_DYNAMIC_TABLE_FACTORY_PROTOCOL *CONST TableFactoryProtocol, + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, + IN CONST SMBIOS_TABLE_GENERATOR *CONST Generator, + IN EFI_SMBIOS_PROTOCOL *SmbiosProtocol, + IN CM_STD_OBJ_SMBIOS_TABLE_INFO *CONST SmbiosTableInfo + ) +{ + EFI_STATUS Status; + EFI_STATUS Status1; + SMBIOS_STRUCTURE *SmbiosTable; + CM_OBJECT_TOKEN CmObjToken; + EFI_SMBIOS_HANDLE TableHandle; + + SmbiosTable = NULL; + Status = Generator->BuildSmbiosTable ( + Generator, + TableFactoryProtocol, + SmbiosTableInfo, + CfgMgrProtocol, + &SmbiosTable, + &CmObjToken + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: Failed to Build Table." \ + " TableGeneratorId = 0x%x. Status = %r\n", + SmbiosTableInfo->TableGeneratorId, + Status + )); + // Free any allocated resources. + goto exit_handler; + } + + if (SmbiosTable == NULL) { + Status = EFI_NOT_FOUND; + goto exit_handler; + } + + TableHandle = SMBIOS_HANDLE_PI_RESERVED; + + // Install SMBIOS table + Status = SmbiosProtocol->Add ( + SmbiosProtocol, + NULL, + &TableHandle, + SmbiosTable + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: Failed to Install SMBIOS Table. Status = %r\n", + Status + )); + // Free any allocated resources. + goto exit_handler; + } + + Status = TableFactoryProtocol->AddSmbiosHandle ( + SmbiosProtocol, + &TableHandle, + CmObjToken, + SmbiosTableInfo->TableGeneratorId + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: Failed to Add SMBIOS Handle. Status = %r\n", + Status + )); + // Free any allocated resources. + goto exit_handler; + } + + DEBUG (( + DEBUG_INFO, + "INFO: SMBIOS Table installed. Status = %r\n", + Status + )); + +exit_handler: + // Free any resources allocated for generating the tables. + if (Generator->FreeTableResources != NULL) { + Status1 = Generator->FreeTableResources ( + Generator, + TableFactoryProtocol, + SmbiosTableInfo, + CfgMgrProtocol, + &SmbiosTable + ); + if (EFI_ERROR (Status1)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: Failed to Free Table Resources." \ + "TableGeneratorId = 0x%x. Status = %r\n", + SmbiosTableInfo->TableGeneratorId, + Status1 + )); + } + + // Return the first error status in case of failure + if (!EFI_ERROR (Status)) { + Status = Status1; + } + } + + return Status; +} + +/** A helper function to build and install multiple SMBIOS tables. + + This is a helper function that invokes the Table generator interface + for building SMBIOS tables. It uses the SmbiosProtocol to install the + tables, then frees the resources allocated for generating it. + + @param [in] TableFactoryProtocol Pointer to the Table Factory Protocol + interface. + @param [in] CfgMgrProtocol Pointer to the Configuration Manager + Protocol Interface. + @param [in] Generator Pointer to the SmbiosTable generator. + @param [in] SmbiosProtocol Pointer to the Smbios protocol. + @param [in] AcpiTableInfo Pointer to the SMBIOS table Info. + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER A parameter is invalid. + @retval EFI_NOT_FOUND Required object is not found. + @retval EFI_BAD_BUFFER_SIZE Size returned by the Configuration Manager + is less than the Object size for the + requested object. +**/ +STATIC +EFI_STATUS +EFIAPI +BuildAndInstallMultipleSmbiosTables ( + IN CONST EDKII_DYNAMIC_TABLE_FACTORY_PROTOCOL *CONST TableFactoryProtocol, + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, + IN CONST SMBIOS_TABLE_GENERATOR *CONST Generator, + IN EFI_SMBIOS_PROTOCOL *SmbiosProtocol, + IN CM_STD_OBJ_SMBIOS_TABLE_INFO *CONST SmbiosTableInfo + ) +{ + EFI_STATUS Status; + EFI_STATUS Status1; + SMBIOS_STRUCTURE **SmbiosTable; + CM_OBJECT_TOKEN *CmObjToken; + EFI_SMBIOS_HANDLE TableHandle; + UINTN TableCount; + UINTN Index; + + TableCount = 0; + Status = Generator->BuildSmbiosTableEx ( + Generator, + TableFactoryProtocol, + SmbiosTableInfo, + CfgMgrProtocol, + &SmbiosTable, + &CmObjToken, + &TableCount + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: Failed to Build Table." \ + " TableGeneratorId = 0x%x. Status = %r\n", + SmbiosTableInfo->TableGeneratorId, + Status + )); + // Free any allocated resources. + goto exit_handler; + } + + if ((SmbiosTable == NULL) || (TableCount == 0)) { + Status = EFI_NOT_FOUND; + DEBUG (( + DEBUG_ERROR, + "%a: TableCount %u SmbiosTable %p \n", + __FUNCTION__, + TableCount, + SmbiosTable + )); + goto exit_handler; + } + + for (Index = 0; Index < TableCount; Index++) { + TableHandle = SMBIOS_HANDLE_PI_RESERVED; + + // Install SMBIOS table + Status = SmbiosProtocol->Add ( + SmbiosProtocol, + NULL, + &TableHandle, + SmbiosTable[Index] + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: Failed to Install SMBIOS Table. Status = %r\n", + Status + )); + // Free any allocated resources. + goto exit_handler; + } + + Status = TableFactoryProtocol->AddSmbiosHandle ( + SmbiosProtocol, + &TableHandle, + CmObjToken[Index], + SmbiosTableInfo->TableGeneratorId + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: Failed to Add SMBIOS Handle. Status = %r\n", + Status + )); + // Free any allocated resources. + goto exit_handler; + } + + DEBUG (( + DEBUG_INFO, + "INFO: SMBIOS Table installed. Status = %r\n", + Status + )); + } + +exit_handler: + // Free any resources allocated for generating the tables. + if (Generator->FreeTableResourcesEx != NULL) { + Status1 = Generator->FreeTableResourcesEx ( + Generator, + TableFactoryProtocol, + SmbiosTableInfo, + CfgMgrProtocol, + &SmbiosTable, + &CmObjToken, + TableCount + ); + if (EFI_ERROR (Status1)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: Failed to Free Table Resources." \ + "TableGeneratorId = 0x%x. Status = %r\n", + SmbiosTableInfo->TableGeneratorId, + Status1 + )); + } + + // Return the first error status in case of failure + if (!EFI_ERROR (Status)) { + Status = Status1; + } + } + + DEBUG ((DEBUG_ERROR, "%a: Returning %r\n", __FUNCTION__, Status)); + return Status; +} + +/** A helper function to invoke a Table generator + + This is a helper function that invokes the Table generator interface + for building an SMBIOS table. It uses the SmbiosProtocol to install the + table, then frees the resources allocated for generating it. + + @param [in] TableFactoryProtocol Pointer to the Table Factory Protocol + interface. + @param [in] CfgMgrProtocol Pointer to the Configuration Manager + Protocol Interface. + @param [in] SmbiosProtocol Pointer to the SMBIOS protocol. + @param [in] SmbiosTableInfo Pointer to the SMBIOS table Info. + + @retval EFI_SUCCESS Success. + @retval EFI_INVALID_PARAMETER A parameter is invalid. + @retval EFI_NOT_FOUND Required object is not found. + @retval EFI_BAD_BUFFER_SIZE Size returned by the Configuration Manager + is less than the Object size for the + requested object. +**/ +EFI_STATUS +EFIAPI +BuildAndInstallSmbiosTable ( + IN CONST EDKII_DYNAMIC_TABLE_FACTORY_PROTOCOL *CONST TableFactoryProtocol, + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol, + IN EFI_SMBIOS_PROTOCOL *SmbiosProtocol, + IN CM_STD_OBJ_SMBIOS_TABLE_INFO *CONST SmbiosTableInfo + ) +{ + EFI_STATUS Status; + CONST SMBIOS_TABLE_GENERATOR *Generator; + + ASSERT (TableFactoryProtocol != NULL); + ASSERT (CfgMgrProtocol != NULL); + ASSERT (SmbiosProtocol != NULL); + ASSERT (SmbiosTableInfo != NULL); + + DEBUG (( + DEBUG_INFO, + "INFO: EStdObjSmbiosTableList: Address = 0x%p," \ + " TableGeneratorId = 0x%x\n", + SmbiosTableInfo, + SmbiosTableInfo->TableGeneratorId + )); + + Generator = NULL; + Status = TableFactoryProtocol->GetSmbiosTableGenerator ( + TableFactoryProtocol, + SmbiosTableInfo->TableGeneratorId, + &Generator + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: Table Generator not found." \ + " TableGeneratorId = 0x%x. Status = %r\n", + SmbiosTableInfo->TableGeneratorId, + Status + )); + return Status; + } + + if (Generator == NULL) { + return EFI_NOT_FOUND; + } + + DEBUG (( + DEBUG_INFO, + "INFO: Generator found : %s\n", + Generator->Description + )); + + if (Generator->BuildSmbiosTableEx != NULL) { + Status = BuildAndInstallMultipleSmbiosTables ( + TableFactoryProtocol, + CfgMgrProtocol, + Generator, + SmbiosProtocol, + SmbiosTableInfo + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: Failed to find build and install SMBIOS Tables." \ + " Status = %r\n", + Status + )); + } + } else if (Generator->BuildSmbiosTable != NULL) { + Status = BuildAndInstallSingleSmbiosTable ( + TableFactoryProtocol, + CfgMgrProtocol, + Generator, + SmbiosProtocol, + SmbiosTableInfo + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: Failed to find build and install SMBIOS Table." \ + " Status = %r\n", + Status + )); + } + } else { + Status = EFI_INVALID_PARAMETER; + DEBUG (( + DEBUG_ERROR, + "ERROR: Table Generator does not implement the" \ + "SMBIOS_TABLE_GENERATOR_BUILD_TABLE interface." \ + " TableGeneratorId = 0x%x. Status = %r\n", + SmbiosTableInfo->TableGeneratorId, + Status + )); + } + + DEBUG ((DEBUG_ERROR, "%a: Returning %r\n", __FUNCTION__, Status)); + return Status; +} + +/** Generate and install SMBIOS tables. + + The function gathers the information necessary for installing the + SMBIOS tables from the Configuration Manager, invokes the generators + and installs them (via BuildAndInstallAcpiTable). + + @param [in] TableFactoryProtocol Pointer to the Table Factory Protocol + interface. + @param [in] CfgMgrProtocol Pointer to the Configuration Manager + Protocol Interface. + + @retval EFI_SUCCESS Success. + @retval EFI_NOT_FOUND If a mandatory table or a generator is not found. +**/ +STATIC +EFI_STATUS +EFIAPI +ProcessSmbiosTables ( + IN CONST EDKII_DYNAMIC_TABLE_FACTORY_PROTOCOL *CONST TableFactoryProtocol, + IN CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL *CONST CfgMgrProtocol + ) +{ + EFI_STATUS Status; + EFI_SMBIOS_PROTOCOL *SmbiosProtocol; + CM_STD_OBJ_SMBIOS_TABLE_INFO *SmbiosTableInfo; + UINT32 SmbiosTableCount; + + Status = gBS->LocateProtocol (&gEfiSmbiosProtocolGuid, NULL, (VOID **)&SmbiosProtocol); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Could not locate SMBIOS protocol. %r\n", Status)); + return Status; + } + + Status = GetEStdObjSmbiosTableList ( + CfgMgrProtocol, + CM_NULL_TOKEN, + &SmbiosTableInfo, + &SmbiosTableCount + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: Failed to get SMBIOS Table List. Status = %r\n", + Status + )); + return Status; + } + + if (SmbiosTableCount == 0) { + DEBUG (( + DEBUG_ERROR, + "ERROR: EStdObjSmbiosTableList: SmbiosTableCount = %d\n", + SmbiosTableCount + )); + return EFI_NOT_FOUND; + } + + DEBUG (( + DEBUG_INFO, + "INFO: EStdObjSmbiosTableList: SmbiosTableCount = %d\n", + SmbiosTableCount + )); + + InitSmbiosTableDispatcher (SmbiosTableInfo, SmbiosTableCount); + + Status = DispatchSmbiosTables ( + TableFactoryProtocol, + CfgMgrProtocol, + SmbiosProtocol, + SmbiosTableInfo, + SmbiosTableCount + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: Failed to install SMBIOS Tables.Status = %r\n", + Status + )); + } + + DEBUG ((DEBUG_ERROR, "%a: Returning %r\n", __FUNCTION__, Status)); + return Status; +} + +/** Callback function for SMBIOS Protocol . + + Callback function for SMBIOS protocol that installs SMBIOS tables + that use the DynamicTables Package. + + @param Event + @param Context + + @retval None +**/ +VOID +EFIAPI +SmbiosProtocolReady ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + EFI_STATUS Status; + EDKII_CONFIGURATION_MANAGER_PROTOCOL *CfgMgrProtocol; + CM_STD_OBJ_CONFIGURATION_MANAGER_INFO *CfgMfrInfo; + EDKII_DYNAMIC_TABLE_FACTORY_PROTOCOL *TableFactoryProtocol; + + // Locate the Dynamic Table Factory + Status = gBS->LocateProtocol ( + &gEdkiiDynamicTableFactoryProtocolGuid, + NULL, + (VOID **)&TableFactoryProtocol + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: Failed to find Dynamic Table Factory protocol." \ + " Status = %r\n", + Status + )); + return; + } + + // Locate the Configuration Manager for the Platform + Status = gBS->LocateProtocol ( + &gEdkiiConfigurationManagerProtocolGuid, + NULL, + (VOID **)&CfgMgrProtocol + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: Failed to find Configuration Manager protocol. Status = %r\n", + Status + )); + return; + } + + Status = GetCgfMgrInfo (CfgMgrProtocol, &CfgMfrInfo); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: Failed to get Configuration Manager info. Status = %r\n", + Status + )); + return; + } + + DEBUG (( + DEBUG_INFO, + "INFO: Configuration Manager Version = 0x%x, OemID = %c%c%c%c%c%c\n", + CfgMfrInfo->Revision, + CfgMfrInfo->OemId[0], + CfgMfrInfo->OemId[1], + CfgMfrInfo->OemId[2], + CfgMfrInfo->OemId[3], + CfgMfrInfo->OemId[4], + CfgMfrInfo->OemId[5] + )); + + Status = ProcessSmbiosTables (TableFactoryProtocol, CfgMgrProtocol); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "ERROR: SMBIOS Table processing failure. Status = %r\n", + Status + )); + } +} -- 2.17.1 -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#107257): https://edk2.groups.io/g/devel/message/107257 Mute This Topic: https://groups.io/mt/100361561/7686176 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io] -=-=-=-=-=-=-=-=-=-=-=-