From nobody Mon Sep 16 19:38:44 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+114522+1787277+3901457@groups.io; arc=fail (BodyHash is different from the expected one) Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1706249043498955.7474037889976; Thu, 25 Jan 2024 22:04:03 -0800 (PST) Return-Path: DKIM-Signature: a=rsa-sha256; bh=xZ4Xzp1FpTCl7zFsLFgtAQRSRx0Ce8iLBD+De42qfrw=; c=relaxed/simple; d=groups.io; h=ARC-Seal:ARC-Message-Signature:ARC-Authentication-Results:Received-SPF:From:To:CC:Subject:Date:Message-ID:In-Reply-To:References:MIME-Version:Precedence:List-Subscribe:List-Help:Sender:List-Id:Mailing-List:Delivered-To:Reply-To:List-Unsubscribe-Post:List-Unsubscribe:Content-Transfer-Encoding:Content-Type; s=20140610; t=1706249043; v=1; b=kTbTNmTqmYguH8FLTj+GB17m0t0tRjaqvfozaRO3gMDVpcvYc92l9Qpt99zOpNwqam8w21yy +xvzH4ii890jo9hPMiWFkH2143UlFl3fMzRdeuhH+Ittc0oAC14cdVOKaE351b0QlRJQAirdlKQ SuCzH9ysUlLJByKfalCwTRdg= X-Received: by 127.0.0.2 with SMTP id h2qdYY1788612xLy6YWyW8h3; Thu, 25 Jan 2024 22:04:03 -0800 X-Received: from NAM12-BN8-obe.outbound.protection.outlook.com (NAM12-BN8-obe.outbound.protection.outlook.com [40.107.237.67]) by mx.groups.io with SMTP id smtpd.web11.9730.1706249042079940603 for ; Thu, 25 Jan 2024 22:04:02 -0800 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=YV/cl5jWhkWAw0R7KyNEs4fuejdvQ2+uXWocbbt+dasioJkbe4JO/B1/DJvF5kuHBK9aKbbz6jPHbPh1LJ1A3VIABgi2wY8SQUMXskIiXiOkazoKINvNBPdTWPSP/LgAaPK3mbcl2/feVInzzA/MhVWejTyDaflAT7kRkB+2xmyh/YqaGaF+XbUdK435OQydWrCdMnw8BU6x6tKfx0S1fNZa63bq3SSFCWhNnBm6XPiYH5QeUwcX9zpKORHZDngPDcaoE9V34MRdLuWhOVDpl0H3xSf29HqqEQQRT1sm8EC13kNi+viFZeSvXkBodLLey5entFN0GrqG/hxypNx7wQ== 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=DkuL7CumDM2txSp3bgvrRQpKaBrAjoRfOFL9gcmml6E=; b=ghyFbWVc/DgHh/sI81DHDOODrBvIZjqk/2lt30d5bmHu7iIGScdRhx2uEhsxO4RYifVuNH4mbZxAeX/pqJKnbx6tzcwf/knWenC6lX4Qbn3TimWUFaCxqA0ZX+jqWmKvkWaPX3mE6KE1FbKg8b0mh5wJmSpiscdA6i6zavIxPXbj57l2nBkxgGnFT/9Qnr33T8I0l+7AJRAaOCcXeHG2/XcAtug5oAa8ZZaM0USssSpx/nanhlz5mau52dKGXFclCfyiWCC7XPQU7NsVL6GsJJJ2AMRMglYslTY6dasLSHJworsfIVrlfwJ7IK50/CtqZoWs2doqENytk6G0qJJWHA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 165.204.84.17) smtp.rcpttodomain=edk2.groups.io smtp.mailfrom=amd.com; dmarc=pass (p=quarantine sp=quarantine pct=100) action=none header.from=amd.com; dkim=none (message not signed); arc=none (0) X-Received: from DM6PR06CA0028.namprd06.prod.outlook.com (2603:10b6:5:120::41) by CYYPR12MB8854.namprd12.prod.outlook.com (2603:10b6:930:b8::6) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7228.26; Fri, 26 Jan 2024 06:03:55 +0000 X-Received: from DS2PEPF0000343E.namprd02.prod.outlook.com (2603:10b6:5:120:cafe::b5) by DM6PR06CA0028.outlook.office365.com (2603:10b6:5:120::41) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7228.27 via Frontend Transport; Fri, 26 Jan 2024 06:03:55 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 165.204.84.17) smtp.mailfrom=amd.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=amd.com; Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+114522+1787277+3901457@groups.io; helo=mail02.groups.io; Received-SPF: Pass (protection.outlook.com: domain of amd.com designates 165.204.84.17 as permitted sender) receiver=protection.outlook.com; client-ip=165.204.84.17; helo=SATLEXMB04.amd.com; pr=C X-Received: from SATLEXMB04.amd.com (165.204.84.17) by DS2PEPF0000343E.mail.protection.outlook.com (10.167.18.41) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.20.7228.16 via Frontend Transport; Fri, 26 Jan 2024 06:03:54 +0000 X-Received: from SHA-LX-MINGXZHA.amd.com (10.180.168.240) by SATLEXMB04.amd.com (10.181.40.145) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.34; Fri, 26 Jan 2024 00:03:52 -0600 From: "Zhai, MingXin (Duke) via groups.io" To: CC: Eric Xing , Duke Zhai , Igniculus Fu , Abner Chang Subject: [edk2-devel] [PATCH V2 30/32] AMD/VanGoghBoard: Check in EDK2 override files Date: Fri, 26 Jan 2024 14:00:48 +0800 Message-ID: <20240126060050.1725-31-duke.zhai@amd.com> In-Reply-To: <20240126060050.1725-1-duke.zhai@amd.com> References: <20240126060050.1725-1-duke.zhai@amd.com> MIME-Version: 1.0 X-Originating-IP: [10.180.168.240] X-ClientProxiedBy: SATLEXMB03.amd.com (10.181.40.144) To SATLEXMB04.amd.com (10.181.40.145) X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: DS2PEPF0000343E:EE_|CYYPR12MB8854:EE_ X-MS-Office365-Filtering-Correlation-Id: 12e07de1-7a59-4262-9b86-08dc1e34940c X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam-Message-Info: EyuB4gVzVjFisygMD789pxRAyZqFnN3rZTMCE/HzmwREPk6lNUNDWvyJpzdkFMePG/S7ouMRLWcrQQFdHB8jwXFJUERj0CljJ02MDOvI6b+Cott83L49DoiINSTT6gc8GOJN4zs1y6t+h2Z2uKhOtRwjkrU4XcVi3o9C8q//xS2vKbR+2vy/XLji5stpoz0xCwm9VdM25FtQ4SWBmswWijz7vXhIy4lF8bmKjPwdEM7YQG9z/3nfN6E5qbhpwA2haby3PpPGNBiGX9SNAPJKcfeV84SjNWBLpkinTgAAUecfb1DXyUGi28mI4OEUfBNa8StZByNUelhc91n5UENwmWHNYUg18+Jpm/aQ9g/AFt7/z1D7IIxrRnH+kPc3ysVti7Tg1bTvecXshF2l0qepJXSSlyA13jcC5gCvMRcYJjiCGs1qcWC6zgqLRhaGsSIQNVh5Tr0jb5WCiTRZ7MwPSqwPrplDOXuHHpE3SZ2jmIiOMt+K4jX83fcu90DXvBaXo6TQ0d8nGl4K+qIQbf1oGeFW6dYaVgOzjYs9IRX52PsYfe3Sv1mWKhM6FgDvYPtqCUbeF2wHCw3xukZZS8GWxHLwlSM2xSFcUsT5rkT9ZgVz2k6b2zrzDU6s2yJSpTwUVRObGcpJn7qW7OALgKYDFb5rO4emC0qgHdRpnUN5LdbYFuGD5Z5lLGqbv15AErxaJnTair1FmWKXn1Ky03IQc1FjnsZ1+4pCjvGZhT4v4uRQdLZrHCg9gkDojLwNZcNEyjW48yFYn71a3rh8gbAda2/pQvEvQCirUnjESwByQCsIHa6ZD0cX0wftu0tfOVpIf9/WY8+zP0wF9FB4eJpTxYnSRAegp8e+bfbwDpptZGTOPeU6zq2Lh5BWpDZFICyzlRssRK+RPMRtp5ZfFZ/2QQ== X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 26 Jan 2024 06:03:54.9973 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 12e07de1-7a59-4262-9b86-08dc1e34940c X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=3dd8961f-e488-4e60-8e11-a82d994e183d;Ip=[165.204.84.17];Helo=[SATLEXMB04.amd.com] X-MS-Exchange-CrossTenant-AuthSource: DS2PEPF0000343E.namprd02.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: CYYPR12MB8854 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,duke.zhai@amd.com List-Unsubscribe-Post: List-Unsubscribe=One-Click List-Unsubscribe: X-Gm-Message-State: RqGep0ZEHn8l8e6dczft4o5Gx1787277AA= Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1706249045448100005 Content-Type: text/plain; charset="utf-8" From: Duke Zhai BZ #:4640 In V2: Improve coding style. 1.Remove the leading underscore and use double underscore at trailing in = C header files. 2.Remove old tianocore licenses and redundant license description. 3.Improve coding style. For example: remove space between @param. In V1: ChachaniBoard Use FSP for open source. FSP is needed to provide some AGESA related pcds as the interface for Platform BIOS. Override those EDK2 files to support reading AGESA-related PCDs from FSP. Signed-off-by: Ken Yao Cc: Eric Xing Cc: Duke Zhai Cc: Igniculus Fu Cc: Abner Chang --- .../edk2/MdeModulePkg/Universal/PCD/Dxe/Pcd.c | 1520 +++++++++++++ .../MdeModulePkg/Universal/PCD/Dxe/Pcd.inf | 366 ++++ .../edk2/MdeModulePkg/Universal/PCD/Pei/Pcd.c | 1876 +++++++++++++++++ .../MdeModulePkg/Universal/PCD/Pei/Pcd.inf | 368 ++++ .../Register/Intel/SmramSaveStateMap.h | 324 +++ 5 files changed, 4454 insertions(+) create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/MdeModulePkg/Un= iversal/PCD/Dxe/Pcd.c create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/MdeModulePkg/Un= iversal/PCD/Dxe/Pcd.inf create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/MdeModulePkg/Un= iversal/PCD/Pei/Pcd.c create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/MdeModulePkg/Un= iversal/PCD/Pei/Pcd.inf create mode 100644 Platform/AMD/VanGoghBoard/Override/edk2/MdePkg/Include/= Register/Intel/SmramSaveStateMap.h diff --git a/Platform/AMD/VanGoghBoard/Override/edk2/MdeModulePkg/Universal= /PCD/Dxe/Pcd.c b/Platform/AMD/VanGoghBoard/Override/edk2/MdeModulePkg/Unive= rsal/PCD/Dxe/Pcd.c new file mode 100644 index 0000000000..5533786b2c --- /dev/null +++ b/Platform/AMD/VanGoghBoard/Override/edk2/MdeModulePkg/Universal/PCD/Dx= e/Pcd.c @@ -0,0 +1,1520 @@ +/** @file + PCD DXE driver manage all PCD entry initialized in PEI phase and DXE pha= se, and + produce the implementation of native PCD protocol and EFI_PCD_PROTOCOL d= efined in + PI 1.4a Vol3. + +Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.
+Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "Service.h" + +extern EFI_GUID gEfiAmdAgesaModulePkgTokenSpaceGuid; +extern EFI_GUID gEfiAmdAgesaPkgTokenSpaceGuid; +extern EFI_GUID gFspEfiGetPcdInfoProtocolGuid; +extern EFI_GUID gFspEfiPcdProtocolGuid; + +// Cache the FSP PiPcd Protocols. +STATIC EFI_PCD_PROTOCOL *CachedFspPiPcdProtocol; +STATIC EFI_GET_PCD_INFO_PROTOCOL *CachedFspPiGetPcdInfoProtocol; + +STATIC +BOOLEAN +CheckPcdInFsp ( + IN CONST EFI_GUID *InputGuid + ) +{ + if ( (FixedPcdGet8 (PcdFspModeSelection) =3D=3D 0) = // Dispatch mode + && ( CompareGuid (InputGuid, &gEfiAmdAgesaModulePkgTokenSpaceGuid) /= / AgesaModulePkg + || CompareGuid (InputGuid, &gEfiAmdAgesaPkgTokenSpaceGuid) /= / AgesaPkg + || CompareGuid (InputGuid, &gAmdFspPkgGuid) /= / FspPkg + || CompareGuid (InputGuid, &gAmdCpmPkgTokenSpaceGuid))) /= / AmdCpmPkg + { + return TRUE; + } + + return FALSE; +} + +VOID +EFIAPI +FspPiPcdProtocolInstalled ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + gBS->LocateProtocol (&gFspEfiPcdProtocolGuid, NULL, (VOID **)&CachedFspP= iPcdProtocol); + gBS->CloseEvent (Event); + return; +} + +VOID +EFIAPI +FspPiGetPcdInfoProtocolInstalled ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + gBS->LocateProtocol (&gFspEfiGetPcdInfoProtocolGuid, NULL, (VOID **)&Cac= hedFspPiGetPcdInfoProtocol); + gBS->CloseEvent (Event); + return; +} + +STATIC EFI_EVENT mFspPiPcdProtocolInstalledEvent; +STATIC EFI_EVENT mFspPiGetPcdInfoProtocolInstalledEvent; + +/// +/// PCD database lock. +/// +EFI_LOCK mPcdDatabaseLock =3D EFI_INITIALIZE_LOCK_VARIABLE (TPL_NOTIFY); + +/// +/// PCD_PROTOCOL the EDKII native implementation which support dynamic +/// type and dynamicEx type PCDs. +/// +PCD_PROTOCOL mPcdInstance =3D { + DxePcdSetSku, + + DxePcdGet8, + DxePcdGet16, + DxePcdGet32, + DxePcdGet64, + DxePcdGetPtr, + DxePcdGetBool, + DxePcdGetSize, + + DxePcdGet8Ex, + DxePcdGet16Ex, + DxePcdGet32Ex, + DxePcdGet64Ex, + DxePcdGetPtrEx, + DxePcdGetBoolEx, + DxePcdGetSizeEx, + + DxePcdSet8, + DxePcdSet16, + DxePcdSet32, + DxePcdSet64, + DxePcdSetPtr, + DxePcdSetBool, + + DxePcdSet8Ex, + DxePcdSet16Ex, + DxePcdSet32Ex, + DxePcdSet64Ex, + DxePcdSetPtrEx, + DxePcdSetBoolEx, + + DxeRegisterCallBackOnSet, + DxeUnRegisterCallBackOnSet, + DxePcdGetNextToken, + DxePcdGetNextTokenSpace +}; + +/// +/// EFI_PCD_PROTOCOL is defined in PI 1.2 Vol 3 which only support dynamic= Ex type +/// PCD. +/// +EFI_PCD_PROTOCOL mEfiPcdInstance =3D { + DxePcdSetSku, + DxePcdGet8Ex, + DxePcdGet16Ex, + DxePcdGet32Ex, + DxePcdGet64Ex, + DxePcdGetPtrEx, + DxePcdGetBoolEx, + DxePcdGetSizeEx, + DxePcdSet8Ex, + DxePcdSet16Ex, + DxePcdSet32Ex, + DxePcdSet64Ex, + DxePcdSetPtrEx, + DxePcdSetBoolEx, + (EFI_PCD_PROTOCOL_CALLBACK_ON_SET)DxeRegisterCallBackOnSet, + (EFI_PCD_PROTOCOL_CANCEL_CALLBACK)DxeUnRegisterCallBackOnSet, + DxePcdGetNextToken, + DxePcdGetNextTokenSpace +}; + +/// +/// Instance of GET_PCD_INFO_PROTOCOL protocol is EDKII native implementat= ion. +/// This protocol instance support dynamic and dynamicEx type PCDs. +/// +GET_PCD_INFO_PROTOCOL mGetPcdInfoInstance =3D { + DxeGetPcdInfoGetInfo, + DxeGetPcdInfoGetInfoEx, + DxeGetPcdInfoGetSku +}; + +/// +/// Instance of EFI_GET_PCD_INFO_PROTOCOL which is defined in PI 1.2.1 Vol= 3. +/// This PPI instance only support dyanmicEx type PCD. +/// +EFI_GET_PCD_INFO_PROTOCOL mEfiGetPcdInfoInstance =3D { + DxeGetPcdInfoGetInfoEx, + DxeGetPcdInfoGetSku +}; + +EFI_HANDLE mPcdHandle =3D NULL; +UINTN mVpdBaseAddress =3D 0; + +/** + Main entry for PCD DXE driver. + + This routine initialize the PCD database and install PCD_PROTOCOL. + + @param ImageHandle Image handle for PCD DXE driver. + @param SystemTable Pointer to SystemTable. + + @return Status of gBS->InstallProtocolInterface() + +**/ +EFI_STATUS +EFIAPI +PcdDxeInit ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + VOID *Registration; + + // + // Make sure the Pcd Protocol is not already installed in the system + // + + ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gPcdProtocolGuid); + + BuildPcdDxeDataBase (); + + // + // Install PCD_PROTOCOL to handle dynamic type PCD + // Install EFI_PCD_PROTOCOL to handle dynamicEx type PCD + // + Status =3D gBS->InstallMultipleProtocolInterfaces ( + &mPcdHandle, + &gPcdProtocolGuid, + &mPcdInstance, + &gEfiPcdProtocolGuid, + &mEfiPcdInstance, + NULL + ); + ASSERT_EFI_ERROR (Status); + + // + // Install GET_PCD_INFO_PROTOCOL to handle dynamic type PCD + // Install EFI_GET_PCD_INFO_PROTOCOL to handle dynamicEx type PCD + // + Status =3D gBS->InstallMultipleProtocolInterfaces ( + &mPcdHandle, + &gGetPcdInfoProtocolGuid, + &mGetPcdInfoInstance, + &gEfiGetPcdInfoProtocolGuid, + &mEfiGetPcdInfoInstance, + NULL + ); + ASSERT_EFI_ERROR (Status); + + // Wait FSP Pcd Protocol. + gBS->CreateEvent (EVT_NOTIFY_SIGNAL, TPL_CALLBACK, FspPiPcdProtocolInsta= lled, NULL, &mFspPiPcdProtocolInstalledEvent); + gBS->RegisterProtocolNotify (&gFspEfiPcdProtocolGuid, mFspPiPcdProtocolI= nstalledEvent, &Registration); + gBS->CreateEvent (EVT_NOTIFY_SIGNAL, TPL_CALLBACK, FspPiGetPcdInfoProtoc= olInstalled, NULL, &mFspPiGetPcdInfoProtocolInstalledEvent); + gBS->RegisterProtocolNotify (&gFspEfiGetPcdInfoProtocolGuid, mFspPiGetPc= dInfoProtocolInstalledEvent, &Registration); + + // + // Register callback function upon VariableLockProtocol + // to lock the variables referenced by DynamicHii PCDs with RO property = set in *.dsc. + // + EfiCreateProtocolNotifyEvent ( + &gEdkiiVariableLockProtocolGuid, + TPL_CALLBACK, + VariableLockCallBack, + NULL, + &Registration + ); + + // + // Cache VpdBaseAddress in entry point for the following usage. + // + + // + // PcdVpdBaseAddress64 is DynamicEx PCD only. So, DxePcdGet64Ex() is use= d to get its value. + // + mVpdBaseAddress =3D (UINTN)DxePcdGet64Ex (&gEfiMdeModulePkgTokenSpaceGui= d, PcdToken (PcdVpdBaseAddress64)); + if (mVpdBaseAddress =3D=3D 0) { + // + // PcdVpdBaseAddress64 is not set, get value from PcdVpdBaseAddress. + // + mVpdBaseAddress =3D (UINTN)PcdGet32 (PcdVpdBaseAddress); + } + + return Status; +} + +/** + Retrieve additional information associated with a PCD token in the defau= lt token space. + + This includes information such as the type of value the TokenNumber is a= ssociated with as well as possible + human readable name that is associated with the token. + + @param[in] TokenNumber The PCD token number. + @param[out] PcdInfo The returned information associated with the r= equested TokenNumber. + The caller is responsible for freeing the buff= er that is allocated by callee for PcdInfo->PcdName. + + @retval EFI_SUCCESS The PCD information was returned successfully. + @retval EFI_NOT_FOUND The PCD service could not find the requested t= oken number. +**/ +EFI_STATUS +EFIAPI +DxeGetPcdInfoGetInfo ( + IN UINTN TokenNumber, + OUT EFI_PCD_INFO *PcdInfo + ) +{ + return DxeGetPcdInfo (NULL, TokenNumber, PcdInfo); +} + +/** + Retrieve additional information associated with a PCD token. + + This includes information such as the type of value the TokenNumber is a= ssociated with as well as possible + human readable name that is associated with the token. + + @param[in] Guid The 128-bit unique value that designates the n= amespace from which to extract the value. + @param[in] TokenNumber The PCD token number. + @param[out] PcdInfo The returned information associated with the r= equested TokenNumber. + The caller is responsible for freeing the buff= er that is allocated by callee for PcdInfo->PcdName. + + @retval EFI_SUCCESS The PCD information was returned successfully. + @retval EFI_NOT_FOUND The PCD service could not find the requested t= oken number. +**/ +EFI_STATUS +EFIAPI +DxeGetPcdInfoGetInfoEx ( + IN CONST EFI_GUID *Guid, + IN UINTN TokenNumber, + OUT EFI_PCD_INFO *PcdInfo + ) +{ + if (CheckPcdInFsp (Guid)) { + ASSERT (CachedFspPiGetPcdInfoProtocol !=3D NULL); + return CachedFspPiGetPcdInfoProtocol->GetInfo (Guid, TokenNumber, PcdI= nfo); + } + + return DxeGetPcdInfo (Guid, TokenNumber, PcdInfo); +} + +/** + Retrieve the currently set SKU Id. + + @return The currently set SKU Id. If the platform has not set at a SKU= Id, then the + default SKU Id value of 0 is returned. If the platform has set= a SKU Id, then the currently set SKU + Id is returned. +**/ +UINTN +EFIAPI +DxeGetPcdInfoGetSku ( + VOID + ) +{ + return (UINTN)mPcdDatabase.DxeDb->SystemSkuId; +} + +/** + Sets the SKU value for subsequent calls to set or get PCD token values. + + SetSku() sets the SKU Id to be used for subsequent calls to set or get P= CD values. + SetSku() is normally called only once by the system. + + For each item (token), the database can hold a single value that applies= to all SKUs, + or multiple values, where each value is associated with a specific SKU I= d. Items with multiple, + SKU-specific values are called SKU enabled. + + The SKU Id of zero is reserved as a default. + For tokens that are not SKU enabled, the system ignores any set SKU Id a= nd works with the + single value for that token. For SKU-enabled tokens, the system will use= the SKU Id set by the + last call to SetSku(). If no SKU Id is set or the currently set SKU Id i= sn't valid for the specified token, + the system uses the default SKU Id. If the system attempts to use the de= fault SKU Id and no value has been + set for that Id, the results are unpredictable. + + @param[in] SkuId The SKU value that will be used when the PCD service w= ill retrieve and + set values associated with a PCD token. + +**/ +VOID +EFIAPI +DxePcdSetSku ( + IN UINTN SkuId + ) +{ + SKU_ID *SkuIdTable; + UINTN Index; + EFI_STATUS Status; + + DEBUG ((DEBUG_INFO, "PcdDxe - SkuId 0x%lx is to be set.\n", (SKU_ID)SkuI= d)); + + if (SkuId =3D=3D mPcdDatabase.DxeDb->SystemSkuId) { + // + // The input SKU Id is equal to current SKU Id, return directly. + // + DEBUG ((DEBUG_INFO, "PcdDxe - SkuId is same to current system Sku.\n")= ); + return; + } + + if (mPcdDatabase.DxeDb->SystemSkuId !=3D (SKU_ID)0) { + DEBUG ((DEBUG_ERROR, "PcdDxe - The SKU Id could be changed only once."= )); + DEBUG (( + DEBUG_ERROR, + "PcdDxe - The SKU Id was set to 0x%lx already, it could not be set t= o 0x%lx any more.", + mPcdDatabase.DxeDb->SystemSkuId, + (SKU_ID)SkuId + )); + ASSERT (FALSE); + return; + } + + SkuIdTable =3D (SKU_ID *)((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.Dxe= Db->SkuIdTableOffset); + for (Index =3D 0; Index < SkuIdTable[0]; Index++) { + if (SkuId =3D=3D SkuIdTable[Index + 1]) { + DEBUG ((DEBUG_INFO, "PcdDxe - SkuId is found in SkuId table.\n")); + Status =3D UpdatePcdDatabase (SkuId, TRUE); + if (!EFI_ERROR (Status)) { + mPcdDatabase.DxeDb->SystemSkuId =3D (SKU_ID)SkuId; + DEBUG ((DEBUG_INFO, "PcdDxe - Set current SKU Id to 0x%lx.\n", (SK= U_ID)SkuId)); + return; + } + } + } + + // + // Invalid input SkuId, the default SKU Id will be still used for the sy= stem. + // + DEBUG ((DEBUG_ERROR, "PcdDxe - Invalid input SkuId, the default SKU Id w= ill be still used.\n")); + return; +} + +/** + Retrieves an 8-bit value for a given PCD token. + + Retrieves the current byte-sized value for a PCD token number. + If the TokenNumber is invalid, the results are unpredictable. + + @param[in] TokenNumber The PCD token number. + + @return The UINT8 value. + +**/ +UINT8 +EFIAPI +DxePcdGet8 ( + IN UINTN TokenNumber + ) +{ + return *((UINT8 *)GetWorker (TokenNumber, sizeof (UINT8))); +} + +/** + Retrieves an 16-bit value for a given PCD token. + + Retrieves the current 16-bits value for a PCD token number. + If the TokenNumber is invalid, the results are unpredictable. + + @param[in] TokenNumber The PCD token number. + + @return The UINT16 value. + +**/ +UINT16 +EFIAPI +DxePcdGet16 ( + IN UINTN TokenNumber + ) +{ + return ReadUnaligned16 (GetWorker (TokenNumber, sizeof (UINT16))); +} + +/** + Retrieves an 32-bit value for a given PCD token. + + Retrieves the current 32-bits value for a PCD token number. + If the TokenNumber is invalid, the results are unpredictable. + + @param[in] TokenNumber The PCD token number. + + @return The UINT32 value. + +**/ +UINT32 +EFIAPI +DxePcdGet32 ( + IN UINTN TokenNumber + ) +{ + return ReadUnaligned32 (GetWorker (TokenNumber, sizeof (UINT32))); +} + +/** + Retrieves an 64-bit value for a given PCD token. + + Retrieves the current 64-bits value for a PCD token number. + If the TokenNumber is invalid, the results are unpredictable. + + @param[in] TokenNumber The PCD token number. + + @return The UINT64 value. + +**/ +UINT64 +EFIAPI +DxePcdGet64 ( + IN UINTN TokenNumber + ) +{ + return ReadUnaligned64 (GetWorker (TokenNumber, sizeof (UINT64))); +} + +/** + Retrieves a pointer to a value for a given PCD token. + + Retrieves the current pointer to the buffer for a PCD token number. + Do not make any assumptions about the alignment of the pointer that + is returned by this function call. If the TokenNumber is invalid, + the results are unpredictable. + + @param[in] TokenNumber The PCD token number. + + @return The pointer to the buffer to be retrived. + +**/ +VOID * +EFIAPI +DxePcdGetPtr ( + IN UINTN TokenNumber + ) +{ + return GetWorker (TokenNumber, 0); +} + +/** + Retrieves a Boolean value for a given PCD token. + + Retrieves the current boolean value for a PCD token number. + Do not make any assumptions about the alignment of the pointer that + is returned by this function call. If the TokenNumber is invalid, + the results are unpredictable. + + @param[in] TokenNumber The PCD token number. + + @return The Boolean value. + +**/ +BOOLEAN +EFIAPI +DxePcdGetBool ( + IN UINTN TokenNumber + ) +{ + return *((BOOLEAN *)GetWorker (TokenNumber, sizeof (BOOLEAN))); +} + +/** + Retrieves the size of the value for a given PCD token. + + Retrieves the current size of a particular PCD token. + If the TokenNumber is invalid, the results are unpredictable. + + @param[in] TokenNumber The PCD token number. + + @return The size of the value for the PCD token. + +**/ +UINTN +EFIAPI +DxePcdGetSize ( + IN UINTN TokenNumber + ) +{ + UINTN Size; + UINT32 *LocalTokenNumberTable; + BOOLEAN IsPeiDb; + UINTN MaxSize; + UINTN TmpTokenNumber; + + // + // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER. + // We have to decrement TokenNumber by 1 to make it usable + // as the array index. + // + TokenNumber--; + + // + // Backup the TokenNumber passed in as GetPtrTypeSize need the original = TokenNumber + // + TmpTokenNumber =3D TokenNumber; + + // EBC compiler is very choosy. It may report warning about comparison + // between UINTN and 0 . So we add 1 in each size of the + // comparison. + ASSERT (TokenNumber + 1 < mPcdTotalTokenCount + 1); + + // EBC compiler is very choosy. It may report warning about comparison + // between UINTN and 0 . So we add 1 in each size of the + // comparison. + IsPeiDb =3D (BOOLEAN)(TokenNumber + 1 < mPeiLocalTokenCount + 1); + + TokenNumber =3D IsPeiDb ? TokenNumber : + (TokenNumber - mPeiLocalTokenCount); + + LocalTokenNumberTable =3D IsPeiDb ? (UINT32 *)((UINT8 *)mPcdDatabase.Pei= Db + mPcdDatabase.PeiDb->LocalTokenNumberTableOffset) + : (UINT32 *)((UINT8 *)mPcdDatabase.DxeDb= + mPcdDatabase.DxeDb->LocalTokenNumberTableOffset); + + Size =3D (LocalTokenNumberTable[TokenNumber] & PCD_DATUM_TYPE_ALL_SET) >= > PCD_DATUM_TYPE_SHIFT; + + if (Size =3D=3D 0) { + // + // For pointer type, we need to scan the SIZE_TABLE to get the current= size. + // + return GetPtrTypeSize (TmpTokenNumber, &MaxSize); + } else { + return Size; + } +} + +/** + Retrieves an 8-bit value for a given PCD token. + + Retrieves the 8-bit value of a particular PCD token. + If the TokenNumber is invalid or the token space + specified by Guid does not exist, the results are + unpredictable. + + @param[in] Guid The token space for the token number. + @param[in] ExTokenNumber The PCD token number. + + @return The size 8-bit value for the PCD token. + +**/ +UINT8 +EFIAPI +DxePcdGet8Ex ( + IN CONST EFI_GUID *Guid, + IN UINTN ExTokenNumber + ) +{ + if (CheckPcdInFsp (Guid)) { + ASSERT (CachedFspPiPcdProtocol !=3D NULL); + return CachedFspPiPcdProtocol->Get8 (Guid, ExTokenNumber); + } + + return *((UINT8 *)ExGetWorker (Guid, ExTokenNumber, sizeof (UINT8))); +} + +/** + Retrieves an 16-bit value for a given PCD token. + + Retrieves the 16-bit value of a particular PCD token. + If the TokenNumber is invalid or the token space + specified by Guid does not exist, the results are + unpredictable. + + @param[in] Guid The token space for the token number. + @param[in] ExTokenNumber The PCD token number. + + @return The size 16-bit value for the PCD token. + +**/ +UINT16 +EFIAPI +DxePcdGet16Ex ( + IN CONST EFI_GUID *Guid, + IN UINTN ExTokenNumber + ) +{ + if (CheckPcdInFsp (Guid)) { + ASSERT (CachedFspPiPcdProtocol !=3D NULL); + return CachedFspPiPcdProtocol->Get16 (Guid, ExTokenNumber); + } + + return ReadUnaligned16 (ExGetWorker (Guid, ExTokenNumber, sizeof (UINT16= ))); +} + +/** + Retrieves an 32-bit value for a given PCD token. + + Retrieves the 32-bit value of a particular PCD token. + If the TokenNumber is invalid or the token space + specified by Guid does not exist, the results are + unpredictable. + + @param[in] Guid The token space for the token number. + @param[in] ExTokenNumber The PCD token number. + + @return The size 32-bit value for the PCD token. + +**/ +UINT32 +EFIAPI +DxePcdGet32Ex ( + IN CONST EFI_GUID *Guid, + IN UINTN ExTokenNumber + ) +{ + if (CheckPcdInFsp (Guid)) { + ASSERT (CachedFspPiPcdProtocol !=3D NULL); + return CachedFspPiPcdProtocol->Get32 (Guid, ExTokenNumber); + } + + return ReadUnaligned32 (ExGetWorker (Guid, ExTokenNumber, sizeof (UINT32= ))); +} + +/** + Retrieves an 64-bit value for a given PCD token. + + Retrieves the 64-bit value of a particular PCD token. + If the TokenNumber is invalid or the token space + specified by Guid does not exist, the results are + unpredictable. + + @param[in] Guid The token space for the token number. + @param[in] ExTokenNumber The PCD token number. + + @return The size 64-bit value for the PCD token. + +**/ +UINT64 +EFIAPI +DxePcdGet64Ex ( + IN CONST EFI_GUID *Guid, + IN UINTN ExTokenNumber + ) +{ + if (CheckPcdInFsp (Guid)) { + ASSERT (CachedFspPiPcdProtocol !=3D NULL); + return CachedFspPiPcdProtocol->Get64 (Guid, ExTokenNumber); + } + + return ReadUnaligned64 (ExGetWorker (Guid, ExTokenNumber, sizeof (UINT64= ))); +} + +/** + Retrieves a pointer to a value for a given PCD token. + + Retrieves the current pointer to the buffer for a PCD token number. + Do not make any assumptions about the alignment of the pointer that + is returned by this function call. If the TokenNumber is invalid, + the results are unpredictable. + + @param[in] Guid The token space for the token number. + @param[in] ExTokenNumber The PCD token number. + + @return The pointer to the buffer to be retrived. + +**/ +VOID * +EFIAPI +DxePcdGetPtrEx ( + IN CONST EFI_GUID *Guid, + IN UINTN ExTokenNumber + ) +{ + if (CheckPcdInFsp (Guid)) { + ASSERT (CachedFspPiPcdProtocol !=3D NULL); + return CachedFspPiPcdProtocol->GetPtr (Guid, ExTokenNumber); + } + + return ExGetWorker (Guid, ExTokenNumber, 0); +} + +/** + Retrieves an Boolean value for a given PCD token. + + Retrieves the Boolean value of a particular PCD token. + If the TokenNumber is invalid or the token space + specified by Guid does not exist, the results are + unpredictable. + + @param[in] Guid The token space for the token number. + @param[in] ExTokenNumber The PCD token number. + + @return The size Boolean value for the PCD token. + +**/ +BOOLEAN +EFIAPI +DxePcdGetBoolEx ( + IN CONST EFI_GUID *Guid, + IN UINTN ExTokenNumber + ) +{ + if (CheckPcdInFsp (Guid)) { + ASSERT (CachedFspPiPcdProtocol !=3D NULL); + return CachedFspPiPcdProtocol->GetBool (Guid, ExTokenNumber); + } + + return *((BOOLEAN *)ExGetWorker (Guid, ExTokenNumber, sizeof (BOOLEAN))); +} + +/** + Retrieves the size of the value for a given PCD token. + + Retrieves the current size of a particular PCD token. + If the TokenNumber is invalid, the results are unpredictable. + + @param[in] Guid The token space for the token number. + @param[in] ExTokenNumber The PCD token number. + + @return The size of the value for the PCD token. + +**/ +UINTN +EFIAPI +DxePcdGetSizeEx ( + IN CONST EFI_GUID *Guid, + IN UINTN ExTokenNumber + ) +{ + if (CheckPcdInFsp (Guid)) { + ASSERT (CachedFspPiPcdProtocol !=3D NULL); + return CachedFspPiPcdProtocol->GetSize (Guid, ExTokenNumber); + } + + return DxePcdGetSize (GetExPcdTokenNumber (Guid, (UINT32)ExTokenNumber)); +} + +/** + Sets an 8-bit value for a given PCD token. + + When the PCD service sets a value, it will check to ensure that the + size of the value being set is compatible with the Token's existing defi= nition. + If it is not, an error will be returned. + + @param[in] TokenNumber The PCD token number. + @param[in] Value The value to set for the PCD token. + + @retval EFI_SUCCESS Procedure returned successfully. + @retval EFI_INVALID_PARAMETER The PCD service determined that the size o= f the data + being set was incompatible with a call t= o this function. + Use GetSize() to retrieve the size of th= e target data. + @retval EFI_NOT_FOUND The PCD service could not find the requested token= number. + +**/ +EFI_STATUS +EFIAPI +DxePcdSet8 ( + IN UINTN TokenNumber, + IN UINT8 Value + ) +{ + return SetValueWorker (TokenNumber, &Value, sizeof (Value)); +} + +/** + Sets an 16-bit value for a given PCD token. + + When the PCD service sets a value, it will check to ensure that the + size of the value being set is compatible with the Token's existing defi= nition. + If it is not, an error will be returned. + + @param[in] TokenNumber The PCD token number. + @param[in] Value The value to set for the PCD token. + + @retval EFI_SUCCESS Procedure returned successfully. + @retval EFI_INVALID_PARAMETER The PCD service determined that the size o= f the data + being set was incompatible with a call t= o this function. + Use GetSize() to retrieve the size of th= e target data. + @retval EFI_NOT_FOUND The PCD service could not find the requested token= number. + +**/ +EFI_STATUS +EFIAPI +DxePcdSet16 ( + IN UINTN TokenNumber, + IN UINT16 Value + ) +{ + return SetValueWorker (TokenNumber, &Value, sizeof (Value)); +} + +/** + Sets an 32-bit value for a given PCD token. + + When the PCD service sets a value, it will check to ensure that the + size of the value being set is compatible with the Token's existing defi= nition. + If it is not, an error will be returned. + + @param[in] TokenNumber The PCD token number. + @param[in] Value The value to set for the PCD token. + + @retval EFI_SUCCESS Procedure returned successfully. + @retval EFI_INVALID_PARAMETER The PCD service determined that the size o= f the data + being set was incompatible with a call t= o this function. + Use GetSize() to retrieve the size of th= e target data. + @retval EFI_NOT_FOUND The PCD service could not find the requested token= number. + +**/ +EFI_STATUS +EFIAPI +DxePcdSet32 ( + IN UINTN TokenNumber, + IN UINT32 Value + ) +{ + return SetValueWorker (TokenNumber, &Value, sizeof (Value)); +} + +/** + Sets an 64-bit value for a given PCD token. + + When the PCD service sets a value, it will check to ensure that the + size of the value being set is compatible with the Token's existing defi= nition. + If it is not, an error will be returned. + + @param[in] TokenNumber The PCD token number. + @param[in] Value The value to set for the PCD token. + + @retval EFI_SUCCESS Procedure returned successfully. + @retval EFI_INVALID_PARAMETER The PCD service determined that the size o= f the data + being set was incompatible with a call t= o this function. + Use GetSize() to retrieve the size of th= e target data. + @retval EFI_NOT_FOUND The PCD service could not find the requested token= number. + +**/ +EFI_STATUS +EFIAPI +DxePcdSet64 ( + IN UINTN TokenNumber, + IN UINT64 Value + ) +{ + return SetValueWorker (TokenNumber, &Value, sizeof (Value)); +} + +/** + Sets a value of a specified size for a given PCD token. + + When the PCD service sets a value, it will check to ensure that the + size of the value being set is compatible with the Token's existing defi= nition. + If it is not, an error will be returned. + + @param[in] TokenNumber The PCD token number. + @param[in, out] SizeOfBuffer A pointer to the length of the value being = set for the PCD token. + On input, if the SizeOfValue is greater than= the maximum size supported + for this TokenNumber then the output value o= f SizeOfValue will reflect + the maximum size supported for this TokenNum= ber. + @param[in] Buffer The buffer to set for the PCD token. + + @retval EFI_SUCCESS Procedure returned successfully. + @retval EFI_INVALID_PARAMETER The PCD service determined that the size o= f the data + being set was incompatible with a call t= o this function. + Use GetSize() to retrieve the size of th= e target data. + @retval EFI_NOT_FOUND The PCD service could not find the requested token= number. + +**/ +EFI_STATUS +EFIAPI +DxePcdSetPtr ( + IN UINTN TokenNumber, + IN OUT UINTN *SizeOfBuffer, + IN VOID *Buffer + ) +{ + return SetWorker (TokenNumber, Buffer, SizeOfBuffer, TRUE); +} + +/** + Sets an Boolean value for a given PCD token. + + When the PCD service sets a value, it will check to ensure that the + size of the value being set is compatible with the Token's existing defi= nition. + If it is not, an error will be returned. + + @param[in] TokenNumber The PCD token number. + @param[in] Value The value to set for the PCD token. + + @retval EFI_SUCCESS Procedure returned successfully. + @retval EFI_INVALID_PARAMETER The PCD service determined that the size o= f the data + being set was incompatible with a call t= o this function. + Use GetSize() to retrieve the size of th= e target data. + @retval EFI_NOT_FOUND The PCD service could not find the requested token= number. + +**/ +EFI_STATUS +EFIAPI +DxePcdSetBool ( + IN UINTN TokenNumber, + IN BOOLEAN Value + ) +{ + return SetValueWorker (TokenNumber, &Value, sizeof (Value)); +} + +/** + Sets an 8-bit value for a given PCD token. + + When the PCD service sets a value, it will check to ensure that the + size of the value being set is compatible with the Token's existing defi= nition. + If it is not, an error will be returned. + + @param[in] Guid The 128-bit unique value that designates the namespace = from which to extract the value. + @param[in] ExTokenNumber The PCD token number. + @param[in] Value The value to set for the PCD token. + + @retval EFI_SUCCESS Procedure returned successfully. + @retval EFI_INVALID_PARAMETER The PCD service determined that the size o= f the data + being set was incompatible with a call t= o this function. + Use GetSize() to retrieve the size of th= e target data. + @retval EFI_NOT_FOUND The PCD service could not find the requested token= number. + +**/ +EFI_STATUS +EFIAPI +DxePcdSet8Ex ( + IN CONST EFI_GUID *Guid, + IN UINTN ExTokenNumber, + IN UINT8 Value + ) +{ + if (CheckPcdInFsp (Guid)) { + ASSERT (CachedFspPiPcdProtocol !=3D NULL); + return CachedFspPiPcdProtocol->Set8 (Guid, ExTokenNumber, Value); + } + + return ExSetValueWorker (ExTokenNumber, Guid, &Value, sizeof (Value)); +} + +/** + Sets an 16-bit value for a given PCD token. + + When the PCD service sets a value, it will check to ensure that the + size of the value being set is compatible with the Token's existing defi= nition. + If it is not, an error will be returned. + + @param[in] Guid The 128-bit unique value that designates the namespace = from which to extract the value. + @param[in] ExTokenNumber The PCD token number. + @param[in] Value The value to set for the PCD token. + + @retval EFI_SUCCESS Procedure returned successfully. + @retval EFI_INVALID_PARAMETER The PCD service determined that the size o= f the data + being set was incompatible with a call t= o this function. + Use GetSize() to retrieve the size of th= e target data. + @retval EFI_NOT_FOUND The PCD service could not find the requested token= number. + +**/ +EFI_STATUS +EFIAPI +DxePcdSet16Ex ( + IN CONST EFI_GUID *Guid, + IN UINTN ExTokenNumber, + IN UINT16 Value + ) +{ + // + // PcdSetNvStoreDefaultId should be set in PEI phase to take effect. + // + ASSERT ( + !(CompareGuid (Guid, &gEfiMdeModulePkgTokenSpaceGuid) && + (ExTokenNumber =3D=3D PcdToken (PcdSetNvStoreDefaultId))) + ); + if (CheckPcdInFsp (Guid)) { + ASSERT (CachedFspPiPcdProtocol !=3D NULL); + return CachedFspPiPcdProtocol->Set16 (Guid, ExTokenNumber, Value); + } + + return ExSetValueWorker (ExTokenNumber, Guid, &Value, sizeof (Value)); +} + +/** + Sets an 32-bit value for a given PCD token. + + When the PCD service sets a value, it will check to ensure that the + size of the value being set is compatible with the Token's existing defi= nition. + If it is not, an error will be returned. + + @param[in] Guid The 128-bit unique value that designates the namespace = from which to extract the value. + @param[in] ExTokenNumber The PCD token number. + @param[in] Value The value to set for the PCD token. + + @retval EFI_SUCCESS Procedure returned successfully. + @retval EFI_INVALID_PARAMETER The PCD service determined that the size o= f the data + being set was incompatible with a call t= o this function. + Use GetSize() to retrieve the size of th= e target data. + @retval EFI_NOT_FOUND The PCD service could not find the requested token= number. + +**/ +EFI_STATUS +EFIAPI +DxePcdSet32Ex ( + IN CONST EFI_GUID *Guid, + IN UINTN ExTokenNumber, + IN UINT32 Value + ) +{ + if (CheckPcdInFsp (Guid)) { + ASSERT (CachedFspPiPcdProtocol !=3D NULL); + return CachedFspPiPcdProtocol->Set32 (Guid, ExTokenNumber, Value); + } + + return ExSetValueWorker (ExTokenNumber, Guid, &Value, sizeof (Value)); +} + +/** + Sets an 64-bit value for a given PCD token. + + When the PCD service sets a value, it will check to ensure that the + size of the value being set is compatible with the Token's existing defi= nition. + If it is not, an error will be returned. + + @param[in] Guid The 128-bit unique value that designates the namespace = from which to extract the value. + @param[in] ExTokenNumber The PCD token number. + @param[in] Value The value to set for the PCD token. + + @retval EFI_SUCCESS Procedure returned successfully. + @retval EFI_INVALID_PARAMETER The PCD service determined that the size o= f the data + being set was incompatible with a call t= o this function. + Use GetSize() to retrieve the size of th= e target data. + @retval EFI_NOT_FOUND The PCD service could not find the requested token= number. + +**/ +EFI_STATUS +EFIAPI +DxePcdSet64Ex ( + IN CONST EFI_GUID *Guid, + IN UINTN ExTokenNumber, + IN UINT64 Value + ) +{ + if (CheckPcdInFsp (Guid)) { + ASSERT (CachedFspPiPcdProtocol !=3D NULL); + return CachedFspPiPcdProtocol->Set64 (Guid, ExTokenNumber, Value); + } + + return ExSetValueWorker (ExTokenNumber, Guid, &Value, sizeof (Value)); +} + +/** + Sets a value of a specified size for a given PCD token. + + When the PCD service sets a value, it will check to ensure that the + size of the value being set is compatible with the Token's existing defi= nition. + If it is not, an error will be returned. + + @param[in] Guid The 128-bit unique value that designates the namespace = from which to extract the value. + @param[in] ExTokenNumber The PCD token number. + @param[in, out] SizeOfBuffer A pointer to the length of the value being = set for the PCD token. + On input, if the SizeOfValue is greater than= the maximum size supported + for this TokenNumber then the output value o= f SizeOfValue will reflect + the maximum size supported for this TokenNum= ber. + @param[in] Buffer The buffer to set for the PCD token. + + @retval EFI_SUCCESS Procedure returned successfully. + @retval EFI_INVALID_PARAMETER The PCD service determined that the size o= f the data + being set was incompatible with a call t= o this function. + Use GetSize() to retrieve the size of th= e target data. + @retval EFI_NOT_FOUND The PCD service could not find the requested token= number. + +**/ +EFI_STATUS +EFIAPI +DxePcdSetPtrEx ( + IN CONST EFI_GUID *Guid, + IN UINTN ExTokenNumber, + IN OUT UINTN *SizeOfBuffer, + IN VOID *Buffer + ) +{ + if (CheckPcdInFsp (Guid)) { + ASSERT (CachedFspPiPcdProtocol !=3D NULL); + return CachedFspPiPcdProtocol->SetPtr (Guid, ExTokenNumber, SizeOfBuff= er, Buffer); + } + + return ExSetWorker (ExTokenNumber, Guid, Buffer, SizeOfBuffer, TRUE); +} + +/** + Sets an Boolean value for a given PCD token. + + When the PCD service sets a value, it will check to ensure that the + size of the value being set is compatible with the Token's existing defi= nition. + If it is not, an error will be returned. + + @param[in] Guid The 128-bit unique value that designates the namespace = from which to extract the value. + @param[in] ExTokenNumber The PCD token number. + @param[in] Value The value to set for the PCD token. + + @retval EFI_SUCCESS Procedure returned successfully. + @retval EFI_INVALID_PARAMETER The PCD service determined that the size o= f the data + being set was incompatible with a call t= o this function. + Use GetSize() to retrieve the size of th= e target data. + @retval EFI_NOT_FOUND The PCD service could not find the requested token= number. + +**/ +EFI_STATUS +EFIAPI +DxePcdSetBoolEx ( + IN CONST EFI_GUID *Guid, + IN UINTN ExTokenNumber, + IN BOOLEAN Value + ) +{ + if (CheckPcdInFsp (Guid)) { + ASSERT (CachedFspPiPcdProtocol !=3D NULL); + return CachedFspPiPcdProtocol->SetBool (Guid, ExTokenNumber, Value); + } + + return ExSetValueWorker (ExTokenNumber, Guid, &Value, sizeof (Value)); +} + +/** + Specifies a function to be called anytime the value of a designated toke= n is changed. + + @param[in] Guid The 128-bit unique value that designates the namespace = from which to extract the value. + @param[in] TokenNumber The PCD token number. + @param[in] CallBackFunction The function prototype called when the valu= e associated with the CallBackToken is set. + + @retval EFI_SUCCESS The PCD service has successfully established a call= event + for the CallBackToken requested. + @retval EFI_NOT_FOUND The PCD service could not find the referenced toke= n number. + +**/ +EFI_STATUS +EFIAPI +DxeRegisterCallBackOnSet ( + IN CONST EFI_GUID *Guid OPTIONAL, + IN UINTN TokenNumber, + IN PCD_PROTOCOL_CALLBACK CallBackFunction + ) +{ + EFI_STATUS Status; + + if (CallBackFunction =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + // + // Aquire lock to prevent reentrance from TPL_CALLBACK level + // + EfiAcquireLock (&mPcdDatabaseLock); + + Status =3D DxeRegisterCallBackWorker (TokenNumber, Guid, CallBackFunctio= n); + + EfiReleaseLock (&mPcdDatabaseLock); + + return Status; +} + +/** + Cancels a previously set callback function for a particular PCD token nu= mber. + + @param[in] Guid The 128-bit unique value that designates the namespace = from which to extract the value. + @param[in] TokenNumber The PCD token number. + @param[in] CallBackFunction The function prototype called when the valu= e associated with the CallBackToken is set. + + @retval EFI_SUCCESS The PCD service has successfully established a call= event + for the CallBackToken requested. + @retval EFI_NOT_FOUND The PCD service could not find the referenced toke= n number. + +**/ +EFI_STATUS +EFIAPI +DxeUnRegisterCallBackOnSet ( + IN CONST EFI_GUID *Guid OPTIONAL, + IN UINTN TokenNumber, + IN PCD_PROTOCOL_CALLBACK CallBackFunction + ) +{ + EFI_STATUS Status; + + if (CallBackFunction =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + // + // Aquire lock to prevent reentrance from TPL_CALLBACK level + // + EfiAcquireLock (&mPcdDatabaseLock); + + Status =3D DxeUnRegisterCallBackWorker (TokenNumber, Guid, CallBackFunct= ion); + + EfiReleaseLock (&mPcdDatabaseLock); + + return Status; +} + +/** + Retrieves the next valid token number in a given namespace. + + This is useful since the PCD infrastructure contains a sparse list of to= ken numbers, + and one cannot a priori know what token numbers are valid in the databas= e. + + If TokenNumber is 0 and Guid is not NULL, then the first token from the = token space specified by Guid is returned. + If TokenNumber is not 0 and Guid is not NULL, then the next token in the= token space specified by Guid is returned. + If TokenNumber is 0 and Guid is NULL, then the first token in the defaul= t token space is returned. + If TokenNumber is not 0 and Guid is NULL, then the next token in the def= ault token space is returned. + The token numbers in the default token space may not be related to token= numbers in token spaces that are named by Guid. + If the next token number can be retrieved, then it is returned in TokenN= umber, and EFI_SUCCESS is returned. + If TokenNumber represents the last token number in the token space speci= fied by Guid, then EFI_NOT_FOUND is returned. + If TokenNumber is not present in the token space specified by Guid, then= EFI_NOT_FOUND is returned. + + + @param[in] Guid The 128-bit unique value that designates the nam= espace from which to retrieve the next token. + This is an optional parameter that may be NULL. = If this parameter is NULL, then a request is + being made to retrieve tokens from the default t= oken space. + @param[in, out] TokenNumber + A pointer to the PCD token number to use to find= the subsequent token number. + + @retval EFI_SUCCESS The PCD service has retrieved the next valid token= number. + @retval EFI_NOT_FOUND The PCD service could not find data from the reque= sted token number. + +**/ +EFI_STATUS +EFIAPI +DxePcdGetNextToken ( + IN CONST EFI_GUID *Guid OPTIONAL, + IN OUT UINTN *TokenNumber + ) +{ + EFI_STATUS Status; + BOOLEAN PeiExMapTableEmpty; + BOOLEAN DxeExMapTableEmpty; + + Status =3D EFI_NOT_FOUND; + PeiExMapTableEmpty =3D mPeiExMapTableEmpty; + DxeExMapTableEmpty =3D mDxeExMapTableEmpty; + + // + // Scan the local token space + // + if (Guid =3D=3D NULL) { + // EBC compiler is very choosy. It may report warning about comparison + // between UINTN and 0 . So we add 1 in each size of the + // comparison. + if (((*TokenNumber + 1 > mPeiNexTokenCount + 1) && (*TokenNumber + 1 <= =3D mPeiLocalTokenCount + 1)) || + ((*TokenNumber + 1 > (mPeiLocalTokenCount + mDxeNexTokenCount + 1)= ))) + { + return EFI_NOT_FOUND; + } + + (*TokenNumber)++; + if ((*TokenNumber + 1 > mPeiNexTokenCount + 1) && + (*TokenNumber + 1 <=3D mPeiLocalTokenCount + 1)) + { + // + // The first Non-Ex type Token Number for DXE PCD + // database is mPeiLocalTokenCount + 1 + // + if (mDxeNexTokenCount > 0) { + *TokenNumber =3D mPeiLocalTokenCount + 1; + } else { + *TokenNumber =3D PCD_INVALID_TOKEN_NUMBER; + return EFI_NOT_FOUND; + } + } else if (*TokenNumber + 1 > mDxeNexTokenCount + mPeiLocalTokenCount = + 1) { + *TokenNumber =3D PCD_INVALID_TOKEN_NUMBER; + return EFI_NOT_FOUND; + } + + return EFI_SUCCESS; + } + + if (PeiExMapTableEmpty && DxeExMapTableEmpty) { + return EFI_NOT_FOUND; + } + + if (!PeiExMapTableEmpty) { + Status =3D ExGetNextTokeNumber ( + Guid, + TokenNumber, + (EFI_GUID *)((UINT8 *)mPcdDatabase.PeiDb + mPcdDatabase.Pei= Db->GuidTableOffset), + mPeiGuidTableSize, + (DYNAMICEX_MAPPING *)((UINT8 *)mPcdDatabase.PeiDb + mPcdDat= abase.PeiDb->ExMapTableOffset), + mPeiExMapppingTableSize + ); + } + + if (Status =3D=3D EFI_SUCCESS) { + return Status; + } + + if (!DxeExMapTableEmpty) { + Status =3D ExGetNextTokeNumber ( + Guid, + TokenNumber, + (EFI_GUID *)((UINT8 *)mPcdDatabase.DxeDb + mPcdDatabase.Dxe= Db->GuidTableOffset), + mDxeGuidTableSize, + (DYNAMICEX_MAPPING *)((UINT8 *)mPcdDatabase.DxeDb + mPcdDat= abase.DxeDb->ExMapTableOffset), + mDxeExMapppingTableSize + ); + } + + return Status; +} + +/** + Get all token space guid table which is different with given token space= guid. + + @param ExMapTableSize The size of ExMapTable in item + @param ExMapTable Token space guid table that want to be scaned. + @param GuidTable Guid table + + @return all token space guid table which is different with given token s= pace guid. + +**/ +EFI_GUID ** +GetDistinctTokenSpace ( + IN OUT UINTN *ExMapTableSize, + IN DYNAMICEX_MAPPING *ExMapTable, + IN EFI_GUID *GuidTable + ) +{ + EFI_GUID **DistinctTokenSpace; + UINTN OldGuidIndex; + UINTN TsIdx; + UINTN TempTsIdx; + UINTN Idx; + BOOLEAN Match; + + DistinctTokenSpace =3D AllocateZeroPool (*ExMapTableSize * sizeof (EFI_G= UID *)); + ASSERT (DistinctTokenSpace !=3D NULL); + + TsIdx =3D 0; + OldGuidIndex =3D ExMapTable[0].ExGuidIndex; + DistinctTokenSpace[TsIdx] =3D &GuidTable[OldGuidIndex]; + for (Idx =3D 1; Idx < *ExMapTableSize; Idx++) { + Match =3D FALSE; + OldGuidIndex =3D ExMapTable[Idx].ExGuidIndex; + for (TempTsIdx =3D 0; TempTsIdx <=3D TsIdx; TempTsIdx++) { + if (&GuidTable[OldGuidIndex] =3D=3D DistinctTokenSpace[TempTsIdx]) { + // + // Have recorded this GUID. + // + Match =3D TRUE; + break; + } + } + + if (!Match) { + DistinctTokenSpace[++TsIdx] =3D &GuidTable[OldGuidIndex]; + } + } + + // + // The total number of Distinct Token Space + // is TsIdx + 1 because we use TsIdx as a index + // to the DistinctTokenSpace[] + // + *ExMapTableSize =3D TsIdx + 1; + return DistinctTokenSpace; +} + +/** + Retrieves the next valid PCD token namespace for a given namespace. + + Gets the next valid token namespace for a given namespace. This is usefu= l to traverse the valid + token namespaces on a platform. + + @param[in, out] Guid An indirect pointer to EFI_GUID. On input it d= esignates a known token + namespace from which the search will start. On= output, it designates the next valid + token namespace on the platform. If *Guid is N= ULL, then the GUID of the first token + space of the current platform is returned. If = the search cannot locate the next valid + token namespace, an error is returned and the = value of *Guid is undefined. + + @retval EFI_SUCCESS The PCD service retrieved the value requested. + @retval EFI_NOT_FOUND The PCD service could not find the next valid = token namespace. + +**/ +EFI_STATUS +EFIAPI +DxePcdGetNextTokenSpace ( + IN OUT CONST EFI_GUID **Guid + ) +{ + UINTN Idx; + UINTN Idx2; + UINTN Idx3; + UINTN PeiTokenSpaceTableSize; + UINTN DxeTokenSpaceTableSize; + EFI_GUID **PeiTokenSpaceTable; + EFI_GUID **DxeTokenSpaceTable; + BOOLEAN Match; + BOOLEAN PeiExMapTableEmpty; + BOOLEAN DxeExMapTableEmpty; + + ASSERT (Guid !=3D NULL); + + PeiExMapTableEmpty =3D mPeiExMapTableEmpty; + DxeExMapTableEmpty =3D mDxeExMapTableEmpty; + + if (PeiExMapTableEmpty && DxeExMapTableEmpty) { + return EFI_NOT_FOUND; + } + + if (TmpTokenSpaceBuffer[0] =3D=3D NULL) { + PeiTokenSpaceTableSize =3D 0; + + if (!PeiExMapTableEmpty) { + PeiTokenSpaceTableSize =3D mPeiExMapppingTableSize / sizeof (DYNAMIC= EX_MAPPING); + PeiTokenSpaceTable =3D GetDistinctTokenSpace ( + &PeiTokenSpaceTableSize, + (DYNAMICEX_MAPPING *)((UINT8 *)mPcdDataba= se.PeiDb + mPcdDatabase.PeiDb->ExMapTableOffset), + (EFI_GUID *)((UINT8 *)mPcdDatabase.PeiDb = + mPcdDatabase.PeiDb->GuidTableOffset) + ); + CopyMem (TmpTokenSpaceBuffer, PeiTokenSpaceTable, sizeof (EFI_GUID *= ) * PeiTokenSpaceTableSize); + TmpTokenSpaceBufferCount =3D PeiTokenSpaceTableSize; + FreePool (PeiTokenSpaceTable); + } + + if (!DxeExMapTableEmpty) { + DxeTokenSpaceTableSize =3D mDxeExMapppingTableSize / sizeof (DYNAMIC= EX_MAPPING); + DxeTokenSpaceTable =3D GetDistinctTokenSpace ( + &DxeTokenSpaceTableSize, + (DYNAMICEX_MAPPING *)((UINT8 *)mPcdDataba= se.DxeDb + mPcdDatabase.DxeDb->ExMapTableOffset), + (EFI_GUID *)((UINT8 *)mPcdDatabase.DxeDb = + mPcdDatabase.DxeDb->GuidTableOffset) + ); + + // + // Make sure EFI_GUID in DxeTokenSpaceTable does not exist in PeiTok= enSpaceTable + // + for (Idx2 =3D 0, Idx3 =3D PeiTokenSpaceTableSize; Idx2 < DxeTokenSpa= ceTableSize; Idx2++) { + Match =3D FALSE; + for (Idx =3D 0; Idx < PeiTokenSpaceTableSize; Idx++) { + if (CompareGuid (TmpTokenSpaceBuffer[Idx], DxeTokenSpaceTable[Id= x2])) { + Match =3D TRUE; + break; + } + } + + if (!Match) { + TmpTokenSpaceBuffer[Idx3++] =3D DxeTokenSpaceTable[Idx2]; + } + } + + TmpTokenSpaceBufferCount =3D Idx3; + FreePool (DxeTokenSpaceTable); + } + } + + if (*Guid =3D=3D NULL) { + *Guid =3D TmpTokenSpaceBuffer[0]; + return EFI_SUCCESS; + } + + for (Idx =3D 0; Idx < TmpTokenSpaceBufferCount; Idx++) { + if (CompareGuid (*Guid, TmpTokenSpaceBuffer[Idx])) { + if (Idx =3D=3D TmpTokenSpaceBufferCount - 1) { + // + // It has been the last token namespace. + // + *Guid =3D NULL; + return EFI_NOT_FOUND; + } else { + Idx++; + *Guid =3D TmpTokenSpaceBuffer[Idx]; + return EFI_SUCCESS; + } + } + } + + return EFI_NOT_FOUND; +} diff --git a/Platform/AMD/VanGoghBoard/Override/edk2/MdeModulePkg/Universal= /PCD/Dxe/Pcd.inf b/Platform/AMD/VanGoghBoard/Override/edk2/MdeModulePkg/Uni= versal/PCD/Dxe/Pcd.inf new file mode 100644 index 0000000000..0799e4cd96 --- /dev/null +++ b/Platform/AMD/VanGoghBoard/Override/edk2/MdeModulePkg/Universal/PCD/Dx= e/Pcd.inf @@ -0,0 +1,366 @@ +## @file +# PCD DXE Module INF file +# +# Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +## @file +# PCD DXE driver manage database contains all dynamic PCD entries and prod= uce the implementation of PCD protocol. +# +# This version PCD DXE depends on the external PCD database binary file, n= ot built in PCD data base. +# There are two PCD Protocols as follows: +# 1) PCD_PROTOCOL +# It is EDKII implementation which support Dynamic/DynamicEx type Pcd= s. +# 2) EFI_PCD_PROTOCOL +# It is defined by PI specification 1.2, Vol 3 which only support dyn= amicEx +# type Pcd. +# +# For dynamicEx type PCD, it is compatible between PCD_PROTOCOL and EFI_PC= D_PROTOCOL. +# PCD DXE driver will produce above two protocols at same time. +# +# PCD database is generated as the separate binary image at build time. Th= e binary image +# will be intergrated into Firmware volume together with PCD driver. +# +# ////////////////////////////////////////////////////////////////////////= //////// +# // = // +# // Introduction of PCD database = // +# // = // +# ////////////////////////////////////////////////////////////////////////= //////// +# +# 1, Introduction +# PCD database hold all dynamic type PCD information. The structure of = PEI PCD +# database is generated by build tools according to dynamic PCD usage f= or +# specified platform. +# +# 2, Dynamic Type PCD +# Dynamic type PCD is used for the configuration/setting which value is= determined +# dynamic. In contrast, the value of static type PCD (FeatureFlag, Fixe= dPcd, +# PatchablePcd) is fixed in final generated FD image in build time. +# +# 2.1 The "dynamic" determination means one of below cases: +# a) The PCD setting value is produced by someone driver and consumed= by +# other driver in execution time. +# b) The PCD setting value is set/get by user from FrontPage. +# c) The PCD setting value is produced by platform OEM vendor in spec= ified area. +# +# 2.2 According to module distribution way, dynamic PCD could be classf= ied as: +# a) Dynamic: +# If module is released in source code and will be built with plat= form +# DSC, the dynamic PCD used by this module can be accessed as: +# PcdGetxx(PcdSampleDynamicPcd); +# In building platform, build tools will translate PcdSampleDynami= cPcd to +# pair of {Token Space Guid: Token Number} for this PCD. +# b) DynamicEx: +# If module is release as binary and will not pariticpate platform= building, +# the dynamic PCD used by this module need be accessed as: +# PcdGetxxEx(gEfiMyTokenspaceGuid, PcdSampleDynamicPcd) +# Developer need explicity gives {Token Space Guid:Token Number} a= s parameter +# in writting source code. +# +# 2.3 According to PCD value's storage method, dynamic PCD could be cla= ssfied as: +# a) Default Storage: +# - The PCD value is stored in PCD database maintained by PCD driv= er in boot +# time memory. +# - This type is used for communication between PEIM/DXE driver, D= XE/DXE +# driver. But all set/get value will be losted after boot-time m= emory +# is turn off. +# - [PcdsDynamicDefault] is used as section name for this type PCD= in +# platform DSC file. [PcdsDynamicExDefault] is used for dynamicE= x type PCD. +# +# b) Variable Storage: +# - The PCD value is stored in variable area. +# - As default storage type, this type PCD could be used for PEI/D= XE driver +# communication. But beside it, this type PCD could also be used= to store +# the value associate with a HII setting via variable interface. +# - In PEI phase, the PCD value could only be got but can not be s= et due +# to variable area is readonly. +# - [PcdsDynamicHii] is used as section name for this type PCD in = platform +# DSC file. [PcdsDynamicExHii] is for dynamicEx type PCD. +# +# c) OEM specificed storage area: +# - The PCD value is stored in OEM specified area which base addre= ss is +# specified by PCD setting - PcdVpdBaseAddress64 or PcdVpdBaseAd= dress. +# - The area is read only for PEI and DXE phase. +# - [PcdsDynamicVpd] is used as section name for this type PCD in = platform +# DSC file. [PcdsDynamicExVpd] is for dynamicex type PCD. +# +# 2.4 When and how to use dynamic PCD +# Module developer do not care the used PCD is dynamic or static when= writting +# source code/INF. Dynamic PCD and dynamic type is pointed by platfor= m integrator +# in platform DSC file. Please ref section 2.3 to get matching betwee= n dynamic +# PCD type and section name in DSC file. +# +# 3, PCD database: +# Although dynamic PCD could be in different storage type as above desc= ription, +# but the basic information and default value for all dynamic PCD is ho= ld +# by PCD database maintained by PEI/DXE driver. +# +# As the whole EFI BIOS boot path is divided into PEI/DXE phase, the PC= D database +# also is divided into Pei/Dxe database maintaied by PcdPeim/PcdDxe dri= ver separatly. +# To make PcdPeim's driver image smaller, PEI PCD database only hold al= l dynamic +# PCD information used in PEI phase or use in both PEI/DXE phase. And D= XE PCD +# database contains all PCDs used in PEI/DXE phase in memory. +# +# Build tool will generate PCD database into the separate binary file f= or +# PEI/DXE PCD driver according to dynamic PCD section in platform DSC f= ile. +# +# 3.1 PcdPeim and PcdDxe +# PEI PCD database is maintained by PcdPeim driver run from flash. Pc= dPeim driver +# build guid hob in temporary memory and copy the binary data base fr= om flash +# to temporary memory for PEI PCD database. +# DXE PCD database is maintained by PcdDxe driver.At entry point of P= cdDxe driver, +# a new PCD database is allocated in boot-time memory which including= all +# PEI PCD and DXE PCD entry. +# +# Pcd driver should run as early as possible before any other driver = access +# dynamic PCD's value. PEI/DXE "Apriori File" mechanism make it possi= ble by +# making PcdPeim/PcdDxe as first dispatching driver in PEI/DXE phase. +# +# 3.2 Token space Guid/Token number, Platform token, Local token number +# Dynamic PCD +# +-----------+ +---------+ +# |TokenSpace | |Platform | +# | Guid | build tool | Token | +# | + +-------------->| Number | +# | Token | +---------+`._ +# | Number | `. +# +-----------+ `. +------+ +# `-|Local | +# |Token | +# DynamicEx PCD ,-|Number| +# +-----------+ ,-' +------+ +# |TokenSpace | ,-' +# | Guid | _,-' +# | + +.' +# | Token | +# | Number | +# +-----------+ +# +# +# 3.2.1 Pair of Token space guid + Token number +# Any type PCD is identified by pair of "TokenSpaceGuid + TokeNumbe= r". But it +# is not easy maintained by PCD driver, and hashed token number wil= l make +# searching slowly. +# +# 3.2.2 Platform Token Number +# "Platform token number" concept is introduced for mapping to a pa= ir of +# "TokenSpaceGuid + TokenNumber". The platform token number is gene= rated by +# build tool in autogen.h and all of them are continual in a platfo= rm scope +# started from 1.(0 meaning invalid internal token number) +# With auto-generated "platform token number", PcdGet(PcdSampleDyna= micPcd) +# in source code is translated to LibPcdGet(_PCD_TOKEN_PcdSampleDyn= amicPcd) +# in autogen.h. +# Notes: The mapping between pair of "tokenspace guid + token numbe= r" and +# "internal token number" need build tool establish, so "platform t= oken number" +# mechanism is not suitable for binary module which use DynamicEx t= ype PCD. +# To access a dynamicEx type PCD, pair of "token space guid/token n= umber" all need +# to be specificed for PcdSet/PcdGet accessing macro. +# +# Platform Token Number is started from 1, and inceased continuous.= From whole +# platform scope, there are two zones: PEI Zone and DXE Zone +# | Platform Token Number +# ----------|------------------------------------------------------= ---------- +# PEI Zone: | 1 ~ PEI_LOCAL_TOKEN_NUMBER +# DXE Zone: | (PEI_LOCAL_TOKEN_NUMBER + 1) ~ (PEI_LOCAL_TOKEN_NUMBE= R + DXE_LOCAL_TOKEN_NUMBER) +# +# 3.2.3 Local Token Number +# To fast searching a PCD entry in PCD database, PCD driver transla= te +# platform token number to local token number via a mapping table. +# For binary DynamicEx type PCD, there is a another mapping table t= o translate +# "token space guid + token number" to local token number directly. +# Local token number is identifier for all internal interface in PC= D PEI/DXE +# driver. +# +# A local token number is a 32-bit value in following meaning: +# 32 ------------- 28 ---------- 24 -------- 0 +# | PCD type mask | Datum Type | Offset | +# +-----------------------------------------+ +# where: +# PCd type mask: indicate Pcd type from following macro: +# PCD_TYPE_DATA +# PCD_TYPE_HII +# PCD_TYPE_VPD +# PCD_TYPE_STRING +# Datum Type : indicate PCD vaue type from following macro: +# PCD_DATUM_TYPE_POINTER +# PCD_DATUM_TYPE_UINT8 +# PCD_DATUM_TYPE_UINT16 +# PCD_DATUM_TYPE_UINT32 +# PCD_DATUM_TYPE_UINT64 +# Offset : indicate the related offset of PCD value in PCD d= atabase array. +# Based on local token number, PCD driver could fast determine PCD t= ype, value +# type and get PCD entry from PCD database. +# +# 3.3 PCD Database binary file +# PCD Database binary file will be created at build time as the stand= alone binary image. +# To understand the binary image layout, PCD Database C structure is = still generated +# as comments by build tools in PCD driver's autogen.h/ +# autogen.c file. In generated C structure, following information is = stored: +# - ExMapTable: This table is used translate a binary dynamicex type = PCD's +# "tokenguid + token" to local token number. +# - LocalTokenNumberTable: +# This table stores all local token number in array, us= e "Internal +# token number" as array index to get PCD entry's offse= t fastly. +# - SizeTable: This table stores the size information for all PCD en= try. +# - GuidTable: This table stores guid value for DynamicEx's token sp= ace, +# HII type PCD's variable GUID. +# - SkuIdTable: TBD +# - SystemSkuId: TBD +# - PCD value structure: +# Every PCD has a value record in PCD database. For dif= ferent +# datum type PCD has different record structure which w= ill be +# introduced in 3.3.1 +# +# In a PCD database structure, there are two major area: Init and UnI= nit. +# Init area is use stored above PCD internal structure such as ExMapT= able, +# LocalTokenNumberTable etc and the (default) value of PCD which has = default +# value specified in platform DSC file. +# Unint area is used stored the value of PCD which has no default val= ue in +# platform DSC file, the value of NULL, 0 specified in platform DSC f= ile can +# be seemed as "no default value". +# +# 3.3.1 Simple Sample PCD Database C Structure +# A general sample of PCD database structue is as follows: +# typedef struct _PCD_DATABASE { +# typedef struct _PCD_DATABASE_INIT { +# //=3D=3D=3D=3D=3D Following is PCD database internal maintain= structures +# DYNAMICEX_MAPPING ExMapTable[PEI_EXMAPPING_TABLE_SIZE]; +# UINT32 LocalTokenNumberTable[PEI_LOCAL_TOKEN_NUMBE= R_TABLE_SIZE]; +# GUID GuidTable[PEI_GUID_TABLE_SIZE]; +# SIZE_INFO SizeTable[PEI_SIZE_TABLE_SIZE]; +# UINT8 SkuIdTable[PEI_SKUID_TABLE_SIZE]; +# SKU_ID SystemSkuId; +# +# //=3D=3D=3D=3D=3D Following is value structure for PCD with d= efault value +# .... +# .... +# .... +# } Init; +# typedef struct _PCD_DATABSE_UNINIT { +# //=3D=3D=3D=3D Following is value structure for PCD without d= efault value +# .... +# .... +# } UnInit; +# } +# +# 3.3.2 PCD value structure in PCD database C structure +# The value's structure is generated by build tool in PCD database = C structure. +# The PCDs in different datum type has different value structure. +# +# 3.3.2.1 UINT8/UINT16/UINT32/UINT64 datum type PCD +# The C structure for these datum type PCD is just a UINT8/UINT16= /UINT32/UINT64 +# data member in PCD database, For example: +# UINT16 PcdHardwareErrorRecordLevel_d3705011_bc19_4af7_be16_f68= 030378c15_VariableDefault_0; +# Above structure is generated by build tool, the member name is = "PcdCName_Guidvalue" +# Member type is UINT16 according to PcdHardwareErrorRecordLevel = declaration +# in DEC file. +# +# 3.3.2.2 VOID* datum type PCD +# The value of VOID* datum type PCD is a UINT8/UINT16 array in PC= D database. +# +# 3.3.2.2.1 VOID* - string type +# If the default value for VOID* datum type PCD like L"xxx", th= e PCD is +# used for unicode string, and C structure of this datum type P= CD is +# UINT16 string array in PCD database, for example: +# UINT16 StringTable[29]; +# The number of 29 in above sample is max size of a unicode str= ing. +# +# If the default value for VOID* datum type PCD like "xxx", the= PCD is +# used for ascii string, and C structure of this datum type PCD= is +# UINT8 string array in PCD database, for example: +# UINT8 StringTable[20]; +# The number of 20 in above sample is max size of a ascii strin= g. +# +# 3.3.2.2.2 VOID* - byte array +# If the default value of VOID* datum type PCD like {'0x29', '0= x01', '0xf2'} +# the PCD is used for byte array. The generated structrue is sa= me as +# above ascii string table, +# UINT8 StringTable[13]; +# The number of 13 in above sample is max size of byte array. +# +# 3.3.3 Some utility structures in PCD Database +# 3.3.3.1 GuidTable +# GuidTable array is used to store all related GUID value in PCD = database: +# - Variable GUID for HII type PCD +# - Token space GUID for dynamicex type PCD +# +# Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +# +## + +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D PcdDxe + MODULE_UNI_FILE =3D PcdDxe.uni + FILE_GUID =3D 80CF7257-87AB-47f9-A3FE-D50B76D89541 + MODULE_TYPE =3D DXE_DRIVER + VERSION_STRING =3D 4.0 + PCD_IS_DRIVER =3D DXE_PCD_DRIVER + ENTRY_POINT =3D PcdDxeInit + +# +# The following information is for reference only and not required by the = build tools. +# +# VALID_ARCHITECTURES =3D IA32 X64 EBC +# + +[Sources] + Pcd.c + Service.c + Service.h + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + ChachaniBoardPkg/Project.dec + Override/edk2/Fsp2WrapperPkg/Fsp2WrapperPkg.dec + +[LibraryClasses] + UefiRuntimeServicesTableLib + BaseMemoryLib + UefiBootServicesTableLib + MemoryAllocationLib + HobLib + UefiDriverEntryPoint + UefiLib + DebugLib + BaseLib + PcdLib + DxeServicesLib + +[Guids] + gPcdDataBaseHobGuid ## SOMETIMES_CONSUMES ## = HOB + gPcdDataBaseSignatureGuid ## CONSUMES ## GUID # PC= D database signature GUID. + gEfiMdeModulePkgTokenSpaceGuid ## SOMETIMES_CONSUMES ## = GUID + gEfiAmdAgesaModulePkgTokenSpaceGuid + gEfiAmdAgesaPkgTokenSpaceGuid + gAmdCpmPkgTokenSpaceGuid + gAmdFspPkgGuid + +[Protocols] + gPcdProtocolGuid ## PRODUCES + gEfiPcdProtocolGuid ## PRODUCES + gGetPcdInfoProtocolGuid ## SOMETIMES_PRODUCES + gEfiGetPcdInfoProtocolGuid ## SOMETIMES_PRODUCES + ## NOTIFY + ## SOMETIMES_CONSUMES + gEdkiiVariableLockProtocolGuid + gFspEfiPcdProtocolGuid + gFspEfiGetPcdInfoProtocolGuid + +[Pcd] + gEfiMdeModulePkgTokenSpaceGuid.PcdVpdBaseAddress ## SOMETIMES_CONSU= MES + gEfiMdeModulePkgTokenSpaceGuid.PcdVpdBaseAddress64 ## SOMETIMES_CONSU= MES + gEfiMdeModulePkgTokenSpaceGuid.PcdSetNvStoreDefaultId ## SOMETIMES_CONSU= MES + gIntelFsp2WrapperTokenSpaceGuid.PcdFspModeSelection + +[Depex] + TRUE + +[UserExtensions.TianoCore."ExtraFiles"] + PcdDxeExtra.uni diff --git a/Platform/AMD/VanGoghBoard/Override/edk2/MdeModulePkg/Universal= /PCD/Pei/Pcd.c b/Platform/AMD/VanGoghBoard/Override/edk2/MdeModulePkg/Unive= rsal/PCD/Pei/Pcd.c new file mode 100644 index 0000000000..2a4045bd36 --- /dev/null +++ b/Platform/AMD/VanGoghBoard/Override/edk2/MdeModulePkg/Universal/PCD/Pe= i/Pcd.c @@ -0,0 +1,1876 @@ +/** @file + All Pcd Ppi services are implemented here. + +Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.
+Copyright (c) 2006 - 2021, Intel Corporation. All rights reserved.
+(C) Copyright 2016 Hewlett Packard Enterprise Development LP
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "Service.h" + +extern EFI_GUID gEfiAmdAgesaModulePkgTokenSpaceGuid; +extern EFI_GUID gEfiAmdAgesaPkgTokenSpaceGuid; +extern EFI_GUID gFspEfiGetPcdInfoPpiGuid; +extern EFI_GUID gFspEfiPeiPcdPpiGuid; + +STATIC +BOOLEAN +CheckPcdInFsp ( + IN CONST EFI_GUID *InputGuid + ) +{ + if ( (FixedPcdGet8 (PcdFspModeSelection) =3D=3D 0) = // Dispatch mode + && ( CompareGuid (InputGuid, &gEfiAmdAgesaModulePkgTokenSpaceGuid) /= / AgesaModulePkg + || CompareGuid (InputGuid, &gEfiAmdAgesaPkgTokenSpaceGuid) /= / AgesaPkg + || CompareGuid (InputGuid, &gAmdFspPkgGuid) /= / FspPkg + || CompareGuid (InputGuid, &gAmdCpmPkgTokenSpaceGuid))) /= / AmdCpmPkg + { + return TRUE; + } + + return FALSE; +} + +/// +/// Instance of PCD_PPI protocol is EDKII native implementation. +/// This protocol instance support dynamic and dynamicEx type PCDs. +/// +PCD_PPI mPcdPpiInstance =3D { + PeiPcdSetSku, + + PeiPcdGet8, + PeiPcdGet16, + PeiPcdGet32, + PeiPcdGet64, + PeiPcdGetPtr, + PeiPcdGetBool, + PeiPcdGetSize, + + PeiPcdGet8Ex, + PeiPcdGet16Ex, + PeiPcdGet32Ex, + PeiPcdGet64Ex, + PeiPcdGetPtrEx, + PeiPcdGetBoolEx, + PeiPcdGetSizeEx, + + PeiPcdSet8, + PeiPcdSet16, + PeiPcdSet32, + PeiPcdSet64, + PeiPcdSetPtr, + PeiPcdSetBool, + + PeiPcdSet8Ex, + PeiPcdSet16Ex, + PeiPcdSet32Ex, + PeiPcdSet64Ex, + PeiPcdSetPtrEx, + PeiPcdSetBoolEx, + + PeiRegisterCallBackOnSet, + PcdUnRegisterCallBackOnSet, + PeiPcdGetNextToken, + PeiPcdGetNextTokenSpace +}; + +/// +/// Instance of EFI_PEI_PCD_PPI which is defined in PI 1.2 Vol 3. +/// This PPI instance only support dyanmicEx type PCD. +/// +EFI_PEI_PCD_PPI mEfiPcdPpiInstance =3D { + PeiPcdSetSku, + + PeiPcdGet8Ex, + PeiPcdGet16Ex, + PeiPcdGet32Ex, + PeiPcdGet64Ex, + PeiPcdGetPtrEx, + PeiPcdGetBoolEx, + PeiPcdGetSizeEx, + PeiPcdSet8Ex, + PeiPcdSet16Ex, + PeiPcdSet32Ex, + PeiPcdSet64Ex, + PeiPcdSetPtrEx, + PeiPcdSetBoolEx, + (EFI_PEI_PCD_PPI_CALLBACK_ON_SET)PeiRegisterCallBackOnSet, + (EFI_PEI_PCD_PPI_CANCEL_CALLBACK)PcdUnRegisterCallBackOnSet, + PeiPcdGetNextToken, + PeiPcdGetNextTokenSpace +}; + +/// +/// Instance of GET_PCD_INFO_PPI protocol is EDKII native implementation. +/// This protocol instance support dynamic and dynamicEx type PCDs. +/// +GET_PCD_INFO_PPI mGetPcdInfoInstance =3D { + PeiGetPcdInfoGetInfo, + PeiGetPcdInfoGetInfoEx, + PeiGetPcdInfoGetSku +}; + +/// +/// Instance of EFI_GET_PCD_INFO_PPI which is defined in PI 1.2.1 Vol 3. +/// This PPI instance only support dyanmicEx type PCD. +/// +EFI_GET_PCD_INFO_PPI mEfiGetPcdInfoInstance =3D { + PeiGetPcdInfoGetInfoEx, + PeiGetPcdInfoGetSku +}; + +EFI_PEI_PPI_DESCRIPTOR mPpiList[] =3D { + { + EFI_PEI_PPI_DESCRIPTOR_PPI, + &gPcdPpiGuid, + &mPcdPpiInstance + }, + { + (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), + &gEfiPeiPcdPpiGuid, + &mEfiPcdPpiInstance + } +}; + +EFI_PEI_PPI_DESCRIPTOR mPpiList2[] =3D { + { + EFI_PEI_PPI_DESCRIPTOR_PPI, + &gGetPcdInfoPpiGuid, + &mGetPcdInfoInstance + }, + { + (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), + &gEfiGetPcdInfoPpiGuid, + &mEfiGetPcdInfoInstance + } +}; + +/** + Callback on SET PcdSetNvStoreDefaultId + + Once PcdSetNvStoreDefaultId is set, the default NV storage will be found= from + PcdNvStoreDefaultValueBuffer, and built into VariableHob. + + @param[in] CallBackGuid The PCD token GUID being set. + @param[in] CallBackToken The PCD token number being set. + @param[in, out] TokenData A pointer to the token data being set. + @param[in] TokenDataSize The size, in bytes, of the data being set. + +**/ +VOID +EFIAPI +PcdSetNvStoreDefaultIdCallBack ( + IN CONST EFI_GUID *CallBackGuid OPTIONAL, + IN UINTN CallBackToken, + IN OUT VOID *TokenData, + IN UINTN TokenDataSize + ) +{ + EFI_STATUS Status; + UINT16 DefaultId; + SKU_ID SkuId; + UINTN FullSize; + UINTN Index; + UINT8 *DataBuffer; + UINT8 *VarStoreHobData; + UINT8 *BufferEnd; + BOOLEAN IsFound; + VARIABLE_STORE_HEADER *NvStoreBuffer; + PCD_DEFAULT_DATA *DataHeader; + PCD_DEFAULT_INFO *DefaultInfo; + PCD_DATA_DELTA *DeltaData; + + DefaultId =3D *(UINT16 *)TokenData; + SkuId =3D GetPcdDatabase ()->SystemSkuId; + IsFound =3D FALSE; + + if (PeiPcdGetSizeEx (&gEfiMdeModulePkgTokenSpaceGuid, PcdToken (PcdNvSto= reDefaultValueBuffer)) > sizeof (PCD_NV_STORE_DEFAULT_BUFFER_HEADER)) { + DataBuffer =3D (UINT8 *)PeiPcdGetPtrEx (&gEfiMdeModulePkgTokenSpaceGui= d, PcdToken (PcdNvStoreDefaultValueBuffer)); + FullSize =3D ((PCD_NV_STORE_DEFAULT_BUFFER_HEADER *)DataBuffer)->Len= gth; + DataHeader =3D (PCD_DEFAULT_DATA *)(DataBuffer + sizeof (PCD_NV_STORE_= DEFAULT_BUFFER_HEADER)); + // + // The first section data includes NV storage default setting. + // + NvStoreBuffer =3D (VARIABLE_STORE_HEADER *)((UINT8 *)DataHeader + si= zeof (DataHeader->DataSize) + DataHeader->HeaderSize); + VarStoreHobData =3D (UINT8 *)BuildGuidHob (&NvStoreBuffer->Signature, = NvStoreBuffer->Size); + ASSERT (VarStoreHobData !=3D NULL); + CopyMem (VarStoreHobData, NvStoreBuffer, NvStoreBuffer->Size); + // + // Find the matched SkuId and DefaultId in the first section + // + DefaultInfo =3D &(DataHeader->DefaultInfo[0]); + BufferEnd =3D (UINT8 *)DataHeader + sizeof (DataHeader->DataSize) + = DataHeader->HeaderSize; + while ((UINT8 *)DefaultInfo < BufferEnd) { + if ((DefaultInfo->DefaultId =3D=3D DefaultId) && (DefaultInfo->SkuId= =3D=3D SkuId)) { + IsFound =3D TRUE; + break; + } + + DefaultInfo++; + } + + // + // Find the matched SkuId and DefaultId in the remaining section + // + Index =3D sizeof (PCD_NV_STORE_DEFAULT_BUFFER_HEADER) + ((DataHea= der->DataSize + 7) & (~7)); + DataHeader =3D (PCD_DEFAULT_DATA *)(DataBuffer + Index); + while (!IsFound && Index < FullSize && DataHeader->DataSize !=3D 0xFFF= FFFFF) { + DefaultInfo =3D &(DataHeader->DefaultInfo[0]); + BufferEnd =3D (UINT8 *)DataHeader + sizeof (DataHeader->DataSize) = + DataHeader->HeaderSize; + while ((UINT8 *)DefaultInfo < BufferEnd) { + if ((DefaultInfo->DefaultId =3D=3D DefaultId) && (DefaultInfo->Sku= Id =3D=3D SkuId)) { + IsFound =3D TRUE; + break; + } + + DefaultInfo++; + } + + if (IsFound) { + DeltaData =3D (PCD_DATA_DELTA *)BufferEnd; + BufferEnd =3D (UINT8 *)DataHeader + DataHeader->DataSize; + while ((UINT8 *)DeltaData < BufferEnd) { + *(VarStoreHobData + DeltaData->Offset) =3D (UINT8)DeltaData->Val= ue; + DeltaData++; + } + + break; + } + + Index =3D (Index + DataHeader->DataSize + 7) & (~7); + DataHeader =3D (PCD_DEFAULT_DATA *)(DataBuffer + Index); + } + } + + Status =3D PcdUnRegisterCallBackOnSet ( + &gEfiMdeModulePkgTokenSpaceGuid, + PcdToken (PcdSetNvStoreDefaultId), + PcdSetNvStoreDefaultIdCallBack + ); + ASSERT_EFI_ERROR (Status); +} + +/** + Report Pei PCD database of all SKUs as Guid HOB so that DxePcd can acces= s it. + + @param PeiServices An indirect pointer to the EFI_PEI_SERVICES tab= le published by the PEI Foundation + @param NotifyDescriptor Address of the notification descriptor data str= ucture. + @param Ppi Address of the PPI that was installed. + + @retval EFI_SUCCESS Successfully update the Boot records. +**/ +EFI_STATUS +EFIAPI +EndOfPeiSignalPpiNotifyCallback ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor, + IN VOID *Ppi + ) +{ + PEI_PCD_DATABASE *Database; + EFI_BOOT_MODE BootMode; + EFI_STATUS Status; + UINTN Instance; + EFI_PEI_FV_HANDLE VolumeHandle; + EFI_PEI_FILE_HANDLE FileHandle; + VOID *PcdDb; + UINT32 Length; + PEI_PCD_DATABASE *PeiPcdDb; + + Status =3D PeiServicesGetBootMode (&BootMode); + ASSERT_EFI_ERROR (Status); + + // + // Don't need to report it on S3 boot. + // + if (BootMode =3D=3D BOOT_ON_S3_RESUME) { + return EFI_SUCCESS; + } + + PeiPcdDb =3D GetPcdDatabase (); + if (PeiPcdDb->SystemSkuId !=3D (SKU_ID)0) { + // + // SkuId has been set. Don't need to report it to DXE phase. + // + return EFI_SUCCESS; + } + + // + // Get full PCD database from PcdPeim FileHandle + // + Instance =3D 0; + FileHandle =3D NULL; + while (TRUE) { + // + // Traverse all firmware volume instances + // + Status =3D PeiServicesFfsFindNextVolume (Instance, &VolumeHandle); + // + // Error should not happen + // + ASSERT_EFI_ERROR (Status); + + // + // Find PcdDb file from the beginning in this firmware volume. + // + FileHandle =3D NULL; + Status =3D PeiServicesFfsFindFileByName (&gEfiCallerIdGuid, Volume= Handle, &FileHandle); + if (!EFI_ERROR (Status)) { + // + // Find PcdPeim FileHandle in this volume + // + break; + } + + // + // We cannot find PcdPeim in this firmware volume, then search the nex= t volume. + // + Instance++; + } + + // + // Find PEI PcdDb and Build second PcdDB GuidHob + // + Status =3D PeiServicesFfsFindSectionData (EFI_SECTION_RAW, FileHandle, &= PcdDb); + ASSERT_EFI_ERROR (Status); + Length =3D PeiPcdDb->LengthForAllSkus; + Database =3D BuildGuidHob (&gPcdDataBaseHobGuid, Length); + CopyMem (Database, PcdDb, Length); + + return EFI_SUCCESS; +} + +EFI_PEI_NOTIFY_DESCRIPTOR mEndOfPeiSignalPpiNotifyList[] =3D { + { + (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMI= NATE_LIST), + &gEfiEndOfPeiSignalPpiGuid, + EndOfPeiSignalPpiNotifyCallback + } +}; + +/** + Main entry for PCD PEIM driver. + + This routine initialize the PCD database for PEI phase and install PCD_P= PI/EFI_PEI_PCD_PPI. + + @param FileHandle Handle of the file being invoked. + @param PeiServices Describes the list of possible PEI Services. + + @return Status of install PCD_PPI + +**/ +EFI_STATUS +EFIAPI +PcdPeimInit ( + IN EFI_PEI_FILE_HANDLE FileHandle, + IN CONST EFI_PEI_SERVICES **PeiServices + ) +{ + EFI_STATUS Status; + + Status =3D PeiServicesRegisterForShadow (FileHandle); + if (Status =3D=3D EFI_ALREADY_STARTED) { + // + // This is now starting in memory, the second time starting. + // + EFI_PEI_PPI_DESCRIPTOR *OldPpiList; + EFI_PEI_PPI_DESCRIPTOR *OldPpiList2; + VOID *Ppi; + VOID *Ppi2; + + OldPpiList =3D NULL; + Status =3D PeiServicesLocatePpi ( + &gPcdPpiGuid, + 0, + &OldPpiList, + &Ppi + ); + ASSERT_EFI_ERROR (Status); + + if (OldPpiList !=3D NULL) { + Status =3D PeiServicesReInstallPpi (OldPpiList, &mPpiList[0]); + ASSERT_EFI_ERROR (Status); + } + + OldPpiList2 =3D NULL; + Status =3D PeiServicesLocatePpi ( + &gGetPcdInfoPpiGuid, + 0, + &OldPpiList2, + &Ppi2 + ); + ASSERT_EFI_ERROR (Status); + + if (OldPpiList2 !=3D NULL) { + Status =3D PeiServicesReInstallPpi (OldPpiList2, &mPpiList2[0]); + ASSERT_EFI_ERROR (Status); + } + + OldPpiList =3D NULL; + Status =3D PeiServicesLocatePpi ( + &gEfiPeiPcdPpiGuid, + 0, + &OldPpiList, + &Ppi + ); + ASSERT_EFI_ERROR (Status); + + if (OldPpiList !=3D NULL) { + Status =3D PeiServicesReInstallPpi (OldPpiList, &mPpiList[1]); + ASSERT_EFI_ERROR (Status); + } + + OldPpiList2 =3D NULL; + Status =3D PeiServicesLocatePpi ( + &gEfiGetPcdInfoPpiGuid, + 0, + &OldPpiList2, + &Ppi2 + ); + ASSERT_EFI_ERROR (Status); + + if (OldPpiList2 !=3D NULL) { + Status =3D PeiServicesReInstallPpi (OldPpiList2, &mPpiList2[1]); + ASSERT_EFI_ERROR (Status); + } + + return Status; + } + + BuildPcdDatabase (FileHandle); + + // + // Install PCD_PPI and EFI_PEI_PCD_PPI. + // + Status =3D PeiServicesInstallPpi (&mPpiList[0]); + ASSERT_EFI_ERROR (Status); + + // + // Install GET_PCD_INFO_PPI and EFI_GET_PCD_INFO_PPI. + // + Status =3D PeiServicesInstallPpi (&mPpiList2[0]); + ASSERT_EFI_ERROR (Status); + + Status =3D PeiServicesNotifyPpi (&mEndOfPeiSignalPpiNotifyList[0]); + ASSERT_EFI_ERROR (Status); + + Status =3D PeiRegisterCallBackOnSet ( + &gEfiMdeModulePkgTokenSpaceGuid, + PcdToken (PcdSetNvStoreDefaultId), + PcdSetNvStoreDefaultIdCallBack + ); + ASSERT_EFI_ERROR (Status); + + return Status; +} + +/** + Retrieve additional information associated with a PCD token in the defau= lt token space. + + This includes information such as the type of value the TokenNumber is a= ssociated with as well as possible + human readable name that is associated with the token. + + @param[in] TokenNumber The PCD token number. + @param[out] PcdInfo The returned information associated with the r= equested TokenNumber. + The caller is responsible for freeing the buff= er that is allocated by callee for PcdInfo->PcdName. + + @retval EFI_SUCCESS The PCD information was returned successfully. + @retval EFI_NOT_FOUND The PCD service could not find the requested t= oken number. +**/ +EFI_STATUS +EFIAPI +PeiGetPcdInfoGetInfo ( + IN UINTN TokenNumber, + OUT EFI_PCD_INFO *PcdInfo + ) +{ + return PeiGetPcdInfo (NULL, TokenNumber, PcdInfo); +} + +/** + Retrieve additional information associated with a PCD token. + + This includes information such as the type of value the TokenNumber is a= ssociated with as well as possible + human readable name that is associated with the token. + + @param[in] Guid The 128-bit unique value that designates the n= amespace from which to extract the value. + @param[in] TokenNumber The PCD token number. + @param[out] PcdInfo The returned information associated with the r= equested TokenNumber. + The caller is responsible for freeing the buff= er that is allocated by callee for PcdInfo->PcdName. + + @retval EFI_SUCCESS The PCD information was returned successfully. + @retval EFI_NOT_FOUND The PCD service could not find the requested t= oken number. +**/ +EFI_STATUS +EFIAPI +PeiGetPcdInfoGetInfoEx ( + IN CONST EFI_GUID *Guid, + IN UINTN TokenNumber, + OUT EFI_PCD_INFO *PcdInfo + ) +{ + if (CheckPcdInFsp (Guid)) { + EFI_GET_PCD_INFO_PPI *FspPcdGetInfoPpi =3D NULL; + PeiServicesLocatePpi (&gFspEfiGetPcdInfoPpiGuid, 0, NULL, (VOID **)&Fs= pPcdGetInfoPpi); + ASSERT (FspPcdGetInfoPpi !=3D NULL); + return FspPcdGetInfoPpi->GetInfo (Guid, TokenNumber, PcdInfo); + } + + return PeiGetPcdInfo (Guid, TokenNumber, PcdInfo); +} + +/** + Retrieve the currently set SKU Id. + + @return The currently set SKU Id. If the platform has not set at a SKU= Id, then the + default SKU Id value of 0 is returned. If the platform has set= a SKU Id, then the currently set SKU + Id is returned. +**/ +UINTN +EFIAPI +PeiGetPcdInfoGetSku ( + VOID + ) +{ + return (UINTN)GetPcdDatabase ()->SystemSkuId; +} + +/** + Sets the SKU value for subsequent calls to set or get PCD token values. + + SetSku() sets the SKU Id to be used for subsequent calls to set or get P= CD values. + SetSku() is normally called only once by the system. + + For each item (token), the database can hold a single value that applies= to all SKUs, + or multiple values, where each value is associated with a specific SKU I= d. Items with multiple, + SKU-specific values are called SKU enabled. + + The SKU Id of zero is reserved as a default. + For tokens that are not SKU enabled, the system ignores any set SKU Id a= nd works with the + single value for that token. For SKU-enabled tokens, the system will use= the SKU Id set by the + last call to SetSku(). If no SKU Id is set or the currently set SKU Id i= sn't valid for the specified token, + the system uses the default SKU Id. If the system attempts to use the de= fault SKU Id and no value has been + set for that Id, the results are unpredictable. + + @param[in] SkuId The SKU value that will be used when the PCD service w= ill retrieve and + set values associated with a PCD token. + +**/ +VOID +EFIAPI +PeiPcdSetSku ( + IN UINTN SkuId + ) +{ + PEI_PCD_DATABASE *PeiPcdDb; + SKU_ID *SkuIdTable; + UINTN Index; + EFI_STATUS Status; + UINTN Instance; + EFI_PEI_FV_HANDLE VolumeHandle; + EFI_PEI_FILE_HANDLE FileHandle; + VOID *PcdDb; + UINT32 Length; + PCD_DATABASE_SKU_DELTA *SkuDelta; + PCD_DATA_DELTA *SkuDeltaData; + + DEBUG ((DEBUG_INFO, "PcdPei - SkuId 0x%lx is to be set.\n", (SKU_ID)SkuI= d)); + + PeiPcdDb =3D GetPcdDatabase (); + + if (SkuId =3D=3D PeiPcdDb->SystemSkuId) { + // + // The input SKU Id is equal to current SKU Id, return directly. + // + DEBUG ((DEBUG_INFO, "PcdPei - SkuId is same to current system Sku.\n")= ); + return; + } + + if (PeiPcdDb->SystemSkuId !=3D (SKU_ID)0) { + DEBUG ((DEBUG_ERROR, "PcdPei - The SKU Id could be changed only once."= )); + DEBUG (( + DEBUG_ERROR, + "PcdPei - The SKU Id was set to 0x%lx already, it could not be set t= o 0x%lx any more.", + PeiPcdDb->SystemSkuId, + (SKU_ID)SkuId + )); + ASSERT (FALSE); + return; + } + + SkuIdTable =3D (SKU_ID *)((UINT8 *)PeiPcdDb + PeiPcdDb->SkuIdTableOffset= ); + for (Index =3D 0; Index < SkuIdTable[0]; Index++) { + if (SkuId =3D=3D SkuIdTable[Index + 1]) { + DEBUG ((DEBUG_INFO, "PcdPei - SkuId is found in SkuId table.\n")); + break; + } + } + + if (Index < SkuIdTable[0]) { + // + // Get full PCD database from PcdPeim FileHandle + // + Instance =3D 0; + FileHandle =3D NULL; + while (TRUE) { + // + // Traverse all firmware volume instances + // + Status =3D PeiServicesFfsFindNextVolume (Instance, &VolumeHandle); + // + // Error should not happen + // + ASSERT_EFI_ERROR (Status); + + // + // Find PcdDb file from the beginning in this firmware volume. + // + FileHandle =3D NULL; + Status =3D PeiServicesFfsFindFileByName (&gEfiCallerIdGuid, Volu= meHandle, &FileHandle); + if (!EFI_ERROR (Status)) { + // + // Find PcdPeim FileHandle in this volume + // + break; + } + + // + // We cannot find PcdPeim in this firmware volume, then search the n= ext volume. + // + Instance++; + } + + // + // Find the delta data between the different Skus + // + Status =3D PeiServicesFfsFindSectionData (EFI_SECTION_RAW, FileHandle,= &PcdDb); + ASSERT_EFI_ERROR (Status); + Length =3D PeiPcdDb->LengthForAllSkus; + Index =3D (PeiPcdDb->Length + 7) & (~7); + SkuDelta =3D NULL; + while (Index < Length) { + SkuDelta =3D (PCD_DATABASE_SKU_DELTA *)((UINT8 *)PcdDb + Index); + if ((SkuDelta->SkuId =3D=3D SkuId) && (SkuDelta->SkuIdCompared =3D= =3D 0)) { + break; + } + + Index =3D (Index + SkuDelta->Length + 7) & (~7); + } + + // + // Patch the delta data into current PCD database + // + if ((Index < Length) && (SkuDelta !=3D NULL)) { + SkuDeltaData =3D (PCD_DATA_DELTA *)(SkuDelta + 1); + while ((UINT8 *)SkuDeltaData < (UINT8 *)SkuDelta + SkuDelta->Length)= { + *((UINT8 *)PeiPcdDb + SkuDeltaData->Offset) =3D (UINT8)SkuDeltaDat= a->Value; + SkuDeltaData++; + } + + PeiPcdDb->SystemSkuId =3D (SKU_ID)SkuId; + DEBUG ((DEBUG_INFO, "PcdPei - Set current SKU Id to 0x%lx.\n", (SKU_= ID)SkuId)); + return; + } + } + + // + // Invalid input SkuId, the default SKU Id will be still used for the sy= stem. + // + DEBUG ((DEBUG_ERROR, "PcdPei - Invalid input SkuId, the default SKU Id w= ill be still used.\n")); + + return; +} + +/** + Retrieves an 8-bit value for a given PCD token. + + Retrieves the current byte-sized value for a PCD token number. + If the TokenNumber is invalid, the results are unpredictable. + + @param[in] TokenNumber The PCD token number. + + @return The UINT8 value. + +**/ +UINT8 +EFIAPI +PeiPcdGet8 ( + IN UINTN TokenNumber + ) +{ + return *((UINT8 *)GetWorker (TokenNumber, sizeof (UINT8))); +} + +/** + Retrieves an 16-bit value for a given PCD token. + + Retrieves the current 16-bits value for a PCD token number. + If the TokenNumber is invalid, the results are unpredictable. + + @param[in] TokenNumber The PCD token number. + + @return The UINT16 value. + +**/ +UINT16 +EFIAPI +PeiPcdGet16 ( + IN UINTN TokenNumber + ) +{ + return ReadUnaligned16 (GetWorker (TokenNumber, sizeof (UINT16))); +} + +/** + Retrieves an 32-bit value for a given PCD token. + + Retrieves the current 32-bits value for a PCD token number. + If the TokenNumber is invalid, the results are unpredictable. + + @param[in] TokenNumber The PCD token number. + + @return The UINT32 value. + +**/ +UINT32 +EFIAPI +PeiPcdGet32 ( + IN UINTN TokenNumber + ) +{ + return ReadUnaligned32 (GetWorker (TokenNumber, sizeof (UINT32))); +} + +/** + Retrieves an 64-bit value for a given PCD token. + + Retrieves the current 64-bits value for a PCD token number. + If the TokenNumber is invalid, the results are unpredictable. + + @param[in] TokenNumber The PCD token number. + + @return The UINT64 value. + +**/ +UINT64 +EFIAPI +PeiPcdGet64 ( + IN UINTN TokenNumber + ) +{ + return ReadUnaligned64 (GetWorker (TokenNumber, sizeof (UINT64))); +} + +/** + Retrieves a pointer to a value for a given PCD token. + + Retrieves the current pointer to the buffer for a PCD token number. + Do not make any assumptions about the alignment of the pointer that + is returned by this function call. If the TokenNumber is invalid, + the results are unpredictable. + + @param[in] TokenNumber The PCD token number. + + @return The pointer to the buffer to be retrieved. + +**/ +VOID * +EFIAPI +PeiPcdGetPtr ( + IN UINTN TokenNumber + ) +{ + return GetWorker (TokenNumber, 0); +} + +/** + Retrieves a Boolean value for a given PCD token. + + Retrieves the current boolean value for a PCD token number. + Do not make any assumptions about the alignment of the pointer that + is returned by this function call. If the TokenNumber is invalid, + the results are unpredictable. + + @param[in] TokenNumber The PCD token number. + + @return The Boolean value. + +**/ +BOOLEAN +EFIAPI +PeiPcdGetBool ( + IN UINTN TokenNumber + ) +{ + return *((BOOLEAN *)GetWorker (TokenNumber, sizeof (BOOLEAN))); +} + +/** + Retrieves the size of the value for a given PCD token. + + Retrieves the current size of a particular PCD token. + If the TokenNumber is invalid, the results are unpredictable. + + @param[in] TokenNumber The PCD token number. + + @return The size of the value for the PCD token. + +**/ +UINTN +EFIAPI +PeiPcdGetSize ( + IN UINTN TokenNumber + ) +{ + PEI_PCD_DATABASE *PeiPcdDb; + UINTN Size; + UINTN MaxSize; + UINT32 LocalTokenCount; + + PeiPcdDb =3D GetPcdDatabase (); + LocalTokenCount =3D PeiPcdDb->LocalTokenCount; + // + // TokenNumber Zero is reserved as PCD_INVALID_TOKEN_NUMBER. + // We have to decrement TokenNumber by 1 to make it usable + // as the array index. + // + TokenNumber--; + + // EBC compiler is very choosy. It may report warning about comparison + // between UINTN and 0 . So we add 1 in each size of the + // comparison. + ASSERT (TokenNumber + 1 < (LocalTokenCount + 1)); + + Size =3D (*((UINT32 *)((UINT8 *)PeiPcdDb + PeiPcdDb->LocalTokenNumberTab= leOffset) + TokenNumber) & PCD_DATUM_TYPE_ALL_SET) >> PCD_DATUM_TYPE_SHIFT; + + if (Size =3D=3D 0) { + // + // For pointer type, we need to scan the SIZE_TABLE to get the current= size. + // + return GetPtrTypeSize (TokenNumber, &MaxSize, PeiPcdDb); + } else { + return Size; + } +} + +/** + Retrieves an 8-bit value for a given PCD token. + + Retrieves the 8-bit value of a particular PCD token. + If the TokenNumber is invalid or the token space + specified by Guid does not exist, the results are + unpredictable. + + @param[in] Guid The token space for the token number. + @param[in] ExTokenNumber The PCD token number. + + @return The size 8-bit value for the PCD token. + +**/ +UINT8 +EFIAPI +PeiPcdGet8Ex ( + IN CONST EFI_GUID *Guid, + IN UINTN ExTokenNumber + ) +{ + if (CheckPcdInFsp (Guid)) { + EFI_PEI_PCD_PPI *FspPcdPpi =3D NULL; + PeiServicesLocatePpi (&gFspEfiPeiPcdPpiGuid, 0, NULL, (VOID **)&FspPcd= Ppi); + ASSERT (FspPcdPpi !=3D NULL); + return FspPcdPpi->Get8 (Guid, ExTokenNumber); + } + + return *((UINT8 *)ExGetWorker (Guid, ExTokenNumber, sizeof (UINT8))); +} + +/** + Retrieves an 16-bit value for a given PCD token. + + Retrieves the 16-bit value of a particular PCD token. + If the TokenNumber is invalid or the token space + specified by Guid does not exist, the results are + unpredictable. + + @param[in] Guid The token space for the token number. + @param[in] ExTokenNumber The PCD token number. + + @return The size 16-bit value for the PCD token. + +**/ +UINT16 +EFIAPI +PeiPcdGet16Ex ( + IN CONST EFI_GUID *Guid, + IN UINTN ExTokenNumber + ) +{ + if (CheckPcdInFsp (Guid)) { + EFI_PEI_PCD_PPI *FspPcdPpi =3D NULL; + PeiServicesLocatePpi (&gFspEfiPeiPcdPpiGuid, 0, NULL, (VOID **)&FspPcd= Ppi); + ASSERT (FspPcdPpi !=3D NULL); + return FspPcdPpi->Get16 (Guid, ExTokenNumber); + } + + return ReadUnaligned16 (ExGetWorker (Guid, ExTokenNumber, sizeof (UINT16= ))); +} + +/** + Retrieves an 32-bit value for a given PCD token. + + Retrieves the 32-bit value of a particular PCD token. + If the TokenNumber is invalid or the token space + specified by Guid does not exist, the results are + unpredictable. + + @param[in] Guid The token space for the token number. + @param[in] ExTokenNumber The PCD token number. + + @return The size 32-bit value for the PCD token. + +**/ +UINT32 +EFIAPI +PeiPcdGet32Ex ( + IN CONST EFI_GUID *Guid, + IN UINTN ExTokenNumber + ) +{ + if (CheckPcdInFsp (Guid)) { + EFI_PEI_PCD_PPI *FspPcdPpi =3D NULL; + PeiServicesLocatePpi (&gFspEfiPeiPcdPpiGuid, 0, NULL, (VOID **)&FspPcd= Ppi); + ASSERT (FspPcdPpi !=3D NULL); + return FspPcdPpi->Get32 (Guid, ExTokenNumber); + } + + return ReadUnaligned32 (ExGetWorker (Guid, ExTokenNumber, sizeof (UINT32= ))); +} + +/** + Retrieves an 64-bit value for a given PCD token. + + Retrieves the 64-bit value of a particular PCD token. + If the TokenNumber is invalid or the token space + specified by Guid does not exist, the results are + unpredictable. + + @param[in] Guid The token space for the token number. + @param[in] ExTokenNumber The PCD token number. + + @return The size 64-bit value for the PCD token. + +**/ +UINT64 +EFIAPI +PeiPcdGet64Ex ( + IN CONST EFI_GUID *Guid, + IN UINTN ExTokenNumber + ) +{ + if (CheckPcdInFsp (Guid)) { + EFI_PEI_PCD_PPI *FspPcdPpi =3D NULL; + PeiServicesLocatePpi (&gFspEfiPeiPcdPpiGuid, 0, NULL, (VOID **)&FspPcd= Ppi); + ASSERT (FspPcdPpi !=3D NULL); + return FspPcdPpi->Get64 (Guid, ExTokenNumber); + } + + return ReadUnaligned64 (ExGetWorker (Guid, ExTokenNumber, sizeof (UINT64= ))); +} + +/** + Retrieves a pointer to a value for a given PCD token. + + Retrieves the current pointer to the buffer for a PCD token number. + Do not make any assumptions about the alignment of the pointer that + is returned by this function call. If the TokenNumber is invalid, + the results are unpredictable. + + @param[in] Guid The token space for the token number. + @param[in] ExTokenNumber The PCD token number. + + @return The pointer to the buffer to be retrieved. + +**/ +VOID * +EFIAPI +PeiPcdGetPtrEx ( + IN CONST EFI_GUID *Guid, + IN UINTN ExTokenNumber + ) +{ + if (CheckPcdInFsp (Guid)) { + EFI_PEI_PCD_PPI *FspPcdPpi =3D NULL; + PeiServicesLocatePpi (&gFspEfiPeiPcdPpiGuid, 0, NULL, (VOID **)&FspPcd= Ppi); + ASSERT (FspPcdPpi !=3D NULL); + return FspPcdPpi->GetPtr (Guid, ExTokenNumber); + } + + return ExGetWorker (Guid, ExTokenNumber, 0); +} + +/** + Retrieves an Boolean value for a given PCD token. + + Retrieves the Boolean value of a particular PCD token. + If the TokenNumber is invalid or the token space + specified by Guid does not exist, the results are + unpredictable. + + @param[in] Guid The token space for the token number. + @param[in] ExTokenNumber The PCD token number. + + @return The size Boolean value for the PCD token. + +**/ +BOOLEAN +EFIAPI +PeiPcdGetBoolEx ( + IN CONST EFI_GUID *Guid, + IN UINTN ExTokenNumber + ) +{ + if (CheckPcdInFsp (Guid)) { + EFI_PEI_PCD_PPI *FspPcdPpi =3D NULL; + PeiServicesLocatePpi (&gFspEfiPeiPcdPpiGuid, 0, NULL, (VOID **)&FspPcd= Ppi); + ASSERT (FspPcdPpi !=3D NULL); + return FspPcdPpi->GetBool (Guid, ExTokenNumber); + } + + return *((BOOLEAN *)ExGetWorker (Guid, ExTokenNumber, sizeof (BOOLEAN))); +} + +/** + Retrieves the size of the value for a given PCD token. + + Retrieves the current size of a particular PCD token. + If the TokenNumber is invalid, the results are unpredictable. + + @param[in] Guid The token space for the token number. + @param[in] ExTokenNumber The PCD token number. + + @return The size of the value for the PCD token. + +**/ +UINTN +EFIAPI +PeiPcdGetSizeEx ( + IN CONST EFI_GUID *Guid, + IN UINTN ExTokenNumber + ) +{ + if (CheckPcdInFsp (Guid)) { + EFI_PEI_PCD_PPI *FspPcdPpi =3D NULL; + PeiServicesLocatePpi (&gFspEfiPeiPcdPpiGuid, 0, NULL, (VOID **)&FspPcd= Ppi); + ASSERT (FspPcdPpi !=3D NULL); + return FspPcdPpi->GetSize (Guid, ExTokenNumber); + } + + return PeiPcdGetSize (GetExPcdTokenNumber (Guid, ExTokenNumber)); +} + +/** + Sets an 8-bit value for a given PCD token. + + When the PCD service sets a value, it will check to ensure that the + size of the value being set is compatible with the Token's existing defi= nition. + If it is not, an error will be returned. + + @param[in] TokenNumber The PCD token number. + @param[in] Value The value to set for the PCD token. + + @retval EFI_SUCCESS Procedure returned successfully. + @retval EFI_INVALID_PARAMETER The PCD service determined that the size o= f the data + being set was incompatible with a call t= o this function. + Use GetSize() to retrieve the size of th= e target data. + @retval EFI_NOT_FOUND The PCD service could not find the requested token= number. + +**/ +EFI_STATUS +EFIAPI +PeiPcdSet8 ( + IN UINTN TokenNumber, + IN UINT8 Value + ) +{ + return SetValueWorker (TokenNumber, &Value, sizeof (Value)); +} + +/** + Sets an 16-bit value for a given PCD token. + + When the PCD service sets a value, it will check to ensure that the + size of the value being set is compatible with the Token's existing defi= nition. + If it is not, an error will be returned. + + @param[in] TokenNumber The PCD token number. + @param[in] Value The value to set for the PCD token. + + @retval EFI_SUCCESS Procedure returned successfully. + @retval EFI_INVALID_PARAMETER The PCD service determined that the size o= f the data + being set was incompatible with a call t= o this function. + Use GetSize() to retrieve the size of th= e target data. + @retval EFI_NOT_FOUND The PCD service could not find the requested token= number. + +**/ +EFI_STATUS +EFIAPI +PeiPcdSet16 ( + IN UINTN TokenNumber, + IN UINT16 Value + ) +{ + return SetValueWorker (TokenNumber, &Value, sizeof (Value)); +} + +/** + Sets an 32-bit value for a given PCD token. + + When the PCD service sets a value, it will check to ensure that the + size of the value being set is compatible with the Token's existing defi= nition. + If it is not, an error will be returned. + + @param[in] TokenNumber The PCD token number. + @param[in] Value The value to set for the PCD token. + + @retval EFI_SUCCESS Procedure returned successfully. + @retval EFI_INVALID_PARAMETER The PCD service determined that the size o= f the data + being set was incompatible with a call t= o this function. + Use GetSize() to retrieve the size of th= e target data. + @retval EFI_NOT_FOUND The PCD service could not find the requested token= number. + +**/ +EFI_STATUS +EFIAPI +PeiPcdSet32 ( + IN UINTN TokenNumber, + IN UINT32 Value + ) +{ + return SetValueWorker (TokenNumber, &Value, sizeof (Value)); +} + +/** + Sets an 64-bit value for a given PCD token. + + When the PCD service sets a value, it will check to ensure that the + size of the value being set is compatible with the Token's existing defi= nition. + If it is not, an error will be returned. + + @param[in] TokenNumber The PCD token number. + @param[in] Value The value to set for the PCD token. + + @retval EFI_SUCCESS Procedure returned successfully. + @retval EFI_INVALID_PARAMETER The PCD service determined that the size o= f the data + being set was incompatible with a call t= o this function. + Use GetSize() to retrieve the size of th= e target data. + @retval EFI_NOT_FOUND The PCD service could not find the requested token= number. + +**/ +EFI_STATUS +EFIAPI +PeiPcdSet64 ( + IN UINTN TokenNumber, + IN UINT64 Value + ) +{ + return SetValueWorker (TokenNumber, &Value, sizeof (Value)); +} + +/** + Sets a value of a specified size for a given PCD token. + + When the PCD service sets a value, it will check to ensure that the + size of the value being set is compatible with the Token's existing defi= nition. + If it is not, an error will be returned. + + @param[in] TokenNumber The PCD token number. + @param[in, out] SizeOfBuffer A pointer to the length of the value being = set for the PCD token. + On input, if the SizeOfValue is greater than= the maximum size supported + for this TokenNumber then the output value o= f SizeOfValue will reflect + the maximum size supported for this TokenNum= ber. + @param[in] Buffer The buffer to set for the PCD token. + + @retval EFI_SUCCESS Procedure returned successfully. + @retval EFI_INVALID_PARAMETER The PCD service determined that the size o= f the data + being set was incompatible with a call t= o this function. + Use GetSize() to retrieve the size of th= e target data. + @retval EFI_NOT_FOUND The PCD service could not find the requested token= number. + +**/ +EFI_STATUS +EFIAPI +PeiPcdSetPtr ( + IN UINTN TokenNumber, + IN OUT UINTN *SizeOfBuffer, + IN VOID *Buffer + ) +{ + return SetWorker (TokenNumber, Buffer, SizeOfBuffer, TRUE); +} + +/** + Sets an Boolean value for a given PCD token. + + When the PCD service sets a value, it will check to ensure that the + size of the value being set is compatible with the Token's existing defi= nition. + If it is not, an error will be returned. + + @param[in] TokenNumber The PCD token number. + @param[in] Value The value to set for the PCD token. + + @retval EFI_SUCCESS Procedure returned successfully. + @retval EFI_INVALID_PARAMETER The PCD service determined that the size o= f the data + being set was incompatible with a call t= o this function. + Use GetSize() to retrieve the size of th= e target data. + @retval EFI_NOT_FOUND The PCD service could not find the requested token= number. + +**/ +EFI_STATUS +EFIAPI +PeiPcdSetBool ( + IN UINTN TokenNumber, + IN BOOLEAN Value + ) +{ + return SetValueWorker (TokenNumber, &Value, sizeof (Value)); +} + +/** + Sets an 8-bit value for a given PCD token. + + When the PCD service sets a value, it will check to ensure that the + size of the value being set is compatible with the Token's existing defi= nition. + If it is not, an error will be returned. + + @param[in] Guid The 128-bit unique value that designates the n= amespace from which to extract the value. + @param[in] ExTokenNumber The PCD token number. + @param[in] Value The value to set for the PCD token. + + @retval EFI_SUCCESS Procedure returned successfully. + @retval EFI_INVALID_PARAMETER The PCD service determined that the size o= f the data + being set was incompatible with a call t= o this function. + Use GetSize() to retrieve the size of th= e target data. + @retval EFI_NOT_FOUND The PCD service could not find the requested token= number. + +**/ +EFI_STATUS +EFIAPI +PeiPcdSet8Ex ( + IN CONST EFI_GUID *Guid, + IN UINTN ExTokenNumber, + IN UINT8 Value + ) +{ + if (CheckPcdInFsp (Guid)) { + EFI_PEI_PCD_PPI *FspPcdPpi =3D NULL; + PeiServicesLocatePpi (&gFspEfiPeiPcdPpiGuid, 0, NULL, (VOID **)&FspPcd= Ppi); + ASSERT (FspPcdPpi !=3D NULL); + return FspPcdPpi->Set8 (Guid, ExTokenNumber, Value); + } + + return ExSetValueWorker (ExTokenNumber, Guid, &Value, sizeof (Value)); +} + +/** + Sets an 16-bit value for a given PCD token. + + When the PCD service sets a value, it will check to ensure that the + size of the value being set is compatible with the Token's existing defi= nition. + If it is not, an error will be returned. + + @param[in] Guid The 128-bit unique value that designates the namespace = from which to extract the value. + @param[in] ExTokenNumber The PCD token number. + @param[in] Value The value to set for the PCD token. + + @retval EFI_SUCCESS Procedure returned successfully. + @retval EFI_INVALID_PARAMETER The PCD service determined that the size o= f the data + being set was incompatible with a call t= o this function. + Use GetSize() to retrieve the size of th= e target data. + @retval EFI_NOT_FOUND The PCD service could not find the requested token= number. + +**/ +EFI_STATUS +EFIAPI +PeiPcdSet16Ex ( + IN CONST EFI_GUID *Guid, + IN UINTN ExTokenNumber, + IN UINT16 Value + ) +{ + if (CheckPcdInFsp (Guid)) { + EFI_PEI_PCD_PPI *FspPcdPpi =3D NULL; + PeiServicesLocatePpi (&gFspEfiPeiPcdPpiGuid, 0, NULL, (VOID **)&FspPcd= Ppi); + ASSERT (FspPcdPpi !=3D NULL); + return FspPcdPpi->Set16 (Guid, ExTokenNumber, Value); + } + + return ExSetValueWorker (ExTokenNumber, Guid, &Value, sizeof (Value)); +} + +/** + Sets an 32-bit value for a given PCD token. + + When the PCD service sets a value, it will check to ensure that the + size of the value being set is compatible with the Token's existing defi= nition. + If it is not, an error will be returned. + + @param[in] Guid The 128-bit unique value that designates the n= amespace from which to extract the value. + @param[in] ExTokenNumber The PCD token number. + @param[in] Value The value to set for the PCD token. + + @retval EFI_SUCCESS Procedure returned successfully. + @retval EFI_INVALID_PARAMETER The PCD service determined that the size o= f the data + being set was incompatible with a call t= o this function. + Use GetSize() to retrieve the size of th= e target data. + @retval EFI_NOT_FOUND The PCD service could not find the requested token= number. + +**/ +EFI_STATUS +EFIAPI +PeiPcdSet32Ex ( + IN CONST EFI_GUID *Guid, + IN UINTN ExTokenNumber, + IN UINT32 Value + ) +{ + if (CheckPcdInFsp (Guid)) { + EFI_PEI_PCD_PPI *FspPcdPpi =3D NULL; + PeiServicesLocatePpi (&gFspEfiPeiPcdPpiGuid, 0, NULL, (VOID **)&FspPcd= Ppi); + ASSERT (FspPcdPpi !=3D NULL); + return FspPcdPpi->Set32 (Guid, ExTokenNumber, Value); + } + + return ExSetValueWorker (ExTokenNumber, Guid, &Value, sizeof (Value)); +} + +/** + Sets an 64-bit value for a given PCD token. + + When the PCD service sets a value, it will check to ensure that the + size of the value being set is compatible with the Token's existing defi= nition. + If it is not, an error will be returned. + + @param[in] Guid The 128-bit unique value that designates the n= amespace from which to extract the value. + @param[in] ExTokenNumber The PCD token number. + @param[in] Value The value to set for the PCD token. + + @retval EFI_SUCCESS Procedure returned successfully. + @retval EFI_INVALID_PARAMETER The PCD service determined that the size o= f the data + being set was incompatible with a call t= o this function. + Use GetSize() to retrieve the size of th= e target data. + @retval EFI_NOT_FOUND The PCD service could not find the requested token= number. + +**/ +EFI_STATUS +EFIAPI +PeiPcdSet64Ex ( + IN CONST EFI_GUID *Guid, + IN UINTN ExTokenNumber, + IN UINT64 Value + ) +{ + if (CheckPcdInFsp (Guid)) { + EFI_PEI_PCD_PPI *FspPcdPpi =3D NULL; + PeiServicesLocatePpi (&gFspEfiPeiPcdPpiGuid, 0, NULL, (VOID **)&FspPcd= Ppi); + ASSERT (FspPcdPpi !=3D NULL); + return FspPcdPpi->Set64 (Guid, ExTokenNumber, Value); + } + + return ExSetValueWorker (ExTokenNumber, Guid, &Value, sizeof (Value)); +} + +/** + Sets a value of a specified size for a given PCD token. + + When the PCD service sets a value, it will check to ensure that the + size of the value being set is compatible with the Token's existing defi= nition. + If it is not, an error will be returned. + + @param[in] Guid The 128-bit unique value that designat= es the namespace from which to extract the value. + @param[in] ExTokenNumber The PCD token number. + @param[in, out] SizeOfBuffer A pointer to the length of the value b= eing set for the PCD token. + On input, if the SizeOfValue is greate= r than the maximum size supported + for this TokenNumber then the output v= alue of SizeOfValue will reflect + the maximum size supported for this To= kenNumber. + @param[in] Value The buffer to set for the PCD token. + + @retval EFI_SUCCESS Procedure returned successfully. + @retval EFI_INVALID_PARAMETER The PCD service determined that the size o= f the data + being set was incompatible with a call t= o this function. + Use GetSize() to retrieve the size of th= e target data. + @retval EFI_NOT_FOUND The PCD service could not find the requested token= number. + +**/ +EFI_STATUS +EFIAPI +PeiPcdSetPtrEx ( + IN CONST EFI_GUID *Guid, + IN UINTN ExTokenNumber, + IN OUT UINTN *SizeOfBuffer, + IN VOID *Value + ) +{ + if (CheckPcdInFsp (Guid)) { + EFI_PEI_PCD_PPI *FspPcdPpi =3D NULL; + PeiServicesLocatePpi (&gFspEfiPeiPcdPpiGuid, 0, NULL, (VOID **)&FspPcd= Ppi); + ASSERT (FspPcdPpi !=3D NULL); + return FspPcdPpi->SetPtr (Guid, ExTokenNumber, SizeOfBuffer, Value); + } + + return ExSetWorker (ExTokenNumber, Guid, Value, SizeOfBuffer, TRUE); +} + +/** + Sets an Boolean value for a given PCD token. + + When the PCD service sets a value, it will check to ensure that the + size of the value being set is compatible with the Token's existing defi= nition. + If it is not, an error will be returned. + + @param [in] Guid The 128-bit unique value that designates the = namespace from which to extract the value. + @param [in] ExTokenNumber The PCD token number. + @param [in] Value The value to set for the PCD token. + + @retval EFI_SUCCESS Procedure returned successfully. + @retval EFI_INVALID_PARAMETER The PCD service determined that the size o= f the data + being set was incompatible with a call t= o this function. + Use GetSize() to retrieve the size of th= e target data. + @retval EFI_NOT_FOUND The PCD service could not find the requested token= number. + +**/ +EFI_STATUS +EFIAPI +PeiPcdSetBoolEx ( + IN CONST EFI_GUID *Guid, + IN UINTN ExTokenNumber, + IN BOOLEAN Value + ) +{ + if (CheckPcdInFsp (Guid)) { + EFI_PEI_PCD_PPI *FspPcdPpi =3D NULL; + PeiServicesLocatePpi (&gFspEfiPeiPcdPpiGuid, 0, NULL, (VOID **)&FspPcd= Ppi); + ASSERT (FspPcdPpi !=3D NULL); + return FspPcdPpi->SetBool (Guid, ExTokenNumber, Value); + } + + return ExSetValueWorker (ExTokenNumber, Guid, &Value, sizeof (Value)); +} + +/** + Specifies a function to be called anytime the value of a designated toke= n is changed. + + @param[in] Guid The 128-bit unique value that designates the namespace = from which to extract the value. + @param[in] ExTokenNumber The PCD token number. + @param[in] CallBackFunction The function prototype called when the valu= e associated with the CallBackToken is set. + + @retval EFI_SUCCESS The PCD service has successfully established a call= event + for the CallBackToken requested. + @retval EFI_NOT_FOUND The PCD service could not find the referenced toke= n number. + +**/ +EFI_STATUS +EFIAPI +PeiRegisterCallBackOnSet ( + IN CONST EFI_GUID *Guid OPTIONAL, + IN UINTN ExTokenNumber, + IN PCD_PPI_CALLBACK CallBackFunction + ) +{ + if (!FeaturePcdGet (PcdPeiFullPcdDatabaseEnable)) { + return EFI_UNSUPPORTED; + } + + if (CallBackFunction =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + return PeiRegisterCallBackWorker (ExTokenNumber, Guid, CallBackFunction,= TRUE); +} + +/** + Cancels a previously set callback function for a particular PCD token nu= mber. + + @param[in] Guid The 128-bit unique value that designates the namespace = from which to extract the value. + @param[in] ExTokenNumber The PCD token number. + @param[in] CallBackFunction The function prototype called when the valu= e associated with the CallBackToken is set. + + @retval EFI_SUCCESS The PCD service has successfully established a call= event + for the CallBackToken requested. + @retval EFI_NOT_FOUND The PCD service could not find the referenced toke= n number. + +**/ +EFI_STATUS +EFIAPI +PcdUnRegisterCallBackOnSet ( + IN CONST EFI_GUID *Guid OPTIONAL, + IN UINTN ExTokenNumber, + IN PCD_PPI_CALLBACK CallBackFunction + ) +{ + if (!FeaturePcdGet (PcdPeiFullPcdDatabaseEnable)) { + return EFI_UNSUPPORTED; + } + + if (CallBackFunction =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + return PeiRegisterCallBackWorker (ExTokenNumber, Guid, CallBackFunction,= FALSE); +} + +/** + Retrieves the next valid token number in a given namespace. + + This is useful since the PCD infrastructure contains a sparse list of to= ken numbers, + and one cannot a priori know what token numbers are valid in the databas= e. + + If TokenNumber is 0 and Guid is not NULL, then the first token from the = token space specified by Guid is returned. + If TokenNumber is not 0 and Guid is not NULL, then the next token in the= token space specified by Guid is returned. + If TokenNumber is 0 and Guid is NULL, then the first token in the defaul= t token space is returned. + If TokenNumber is not 0 and Guid is NULL, then the next token in the def= ault token space is returned. + The token numbers in the default token space may not be related to token= numbers in token spaces that are named by Guid. + If the next token number can be retrieved, then it is returned in TokenN= umber, and EFI_SUCCESS is returned. + If TokenNumber represents the last token number in the token space speci= fied by Guid, then EFI_NOT_FOUND is returned. + If TokenNumber is not present in the token space specified by Guid, then= EFI_NOT_FOUND is returned. + + + @param[in] Guid The 128-bit unique value that designates th= e namespace from which to extract the value. + This is an optional parameter that may be N= ULL. If this parameter is NULL, then a request + is being made to retrieve tokens from the d= efault token space. + @param[in, out] TokenNumber A pointer to the PCD token number to use to= find the subsequent token number. + + @retval EFI_SUCCESS The PCD service has retrieved the next valid token= number. + @retval EFI_NOT_FOUND The PCD service could not find data from the reque= sted token number. + +**/ +EFI_STATUS +EFIAPI +PeiPcdGetNextToken ( + IN CONST EFI_GUID *Guid OPTIONAL, + IN OUT UINTN *TokenNumber + ) +{ + UINTN GuidTableIdx; + PEI_PCD_DATABASE *PeiPcdDb; + EFI_GUID *MatchGuid; + EFI_GUID *GuidTable; + DYNAMICEX_MAPPING *ExMapTable; + UINTN Index; + BOOLEAN Found; + BOOLEAN PeiExMapTableEmpty; + UINTN PeiNexTokenNumber; + + if (!FeaturePcdGet (PcdPeiFullPcdDatabaseEnable)) { + return EFI_UNSUPPORTED; + } + + PeiPcdDb =3D GetPcdDatabase (); + PeiNexTokenNumber =3D PeiPcdDb->LocalTokenCount - PeiPcdDb->ExTokenCount; + GuidTable =3D (EFI_GUID *)((UINT8 *)PeiPcdDb + PeiPcdDb->GuidTab= leOffset); + + if (PeiPcdDb->ExTokenCount =3D=3D 0) { + PeiExMapTableEmpty =3D TRUE; + } else { + PeiExMapTableEmpty =3D FALSE; + } + + if (Guid =3D=3D NULL) { + if (*TokenNumber > PeiNexTokenNumber) { + return EFI_NOT_FOUND; + } + + (*TokenNumber)++; + if (*TokenNumber > PeiNexTokenNumber) { + *TokenNumber =3D PCD_INVALID_TOKEN_NUMBER; + return EFI_NOT_FOUND; + } + + return EFI_SUCCESS; + } else { + if (PeiExMapTableEmpty) { + return EFI_NOT_FOUND; + } + + MatchGuid =3D ScanGuid (GuidTable, PeiPcdDb->GuidTableCount * sizeof (= EFI_GUID), Guid); + + if (MatchGuid =3D=3D NULL) { + return EFI_NOT_FOUND; + } + + GuidTableIdx =3D MatchGuid - GuidTable; + + ExMapTable =3D (DYNAMICEX_MAPPING *)((UINT8 *)PeiPcdDb + PeiPcdDb->ExM= apTableOffset); + + Found =3D FALSE; + // + // Locate the GUID in ExMapTable first. + // + for (Index =3D 0; Index < PeiPcdDb->ExTokenCount; Index++) { + if (ExMapTable[Index].ExGuidIndex =3D=3D GuidTableIdx) { + Found =3D TRUE; + break; + } + } + + if (Found) { + // + // If given token number is PCD_INVALID_TOKEN_NUMBER, then return th= e first + // token number in found token space. + // + if (*TokenNumber =3D=3D PCD_INVALID_TOKEN_NUMBER) { + *TokenNumber =3D ExMapTable[Index].ExTokenNumber; + return EFI_SUCCESS; + } + + for ( ; Index < PeiPcdDb->ExTokenCount; Index++) { + if ((ExMapTable[Index].ExTokenNumber =3D=3D *TokenNumber) && (ExMa= pTable[Index].ExGuidIndex =3D=3D GuidTableIdx)) { + break; + } + } + + while (Index < PeiPcdDb->ExTokenCount) { + Index++; + if (Index =3D=3D PeiPcdDb->ExTokenCount) { + // + // Exceed the length of ExMap Table + // + *TokenNumber =3D PCD_INVALID_TOKEN_NUMBER; + return EFI_NOT_FOUND; + } else if (ExMapTable[Index].ExGuidIndex =3D=3D GuidTableIdx) { + // + // Found the next match + // + *TokenNumber =3D ExMapTable[Index].ExTokenNumber; + return EFI_SUCCESS; + } + } + } + } + + return EFI_NOT_FOUND; +} + +/** + Retrieves the next valid PCD token namespace for a given namespace. + + Gets the next valid token namespace for a given namespace. This is usefu= l to traverse the valid + token namespaces on a platform. + + @param[in, out] Guid An indirect pointer to EFI_GUID. On input it d= esignates a known token + namespace from which the search will start. On= output, it designates the next valid + token namespace on the platform. If *Guid is N= ULL, then the GUID of the first token + space of the current platform is returned. If = the search cannot locate the next valid + token namespace, an error is returned and the = value of *Guid is undefined. + + @retval EFI_SUCCESS The PCD service retrieved the value requested. + @retval EFI_NOT_FOUND The PCD service could not find the next valid = token namespace. + +**/ +EFI_STATUS +EFIAPI +PeiPcdGetNextTokenSpace ( + IN OUT CONST EFI_GUID **Guid + ) +{ + UINTN GuidTableIdx; + EFI_GUID *MatchGuid; + PEI_PCD_DATABASE *PeiPcdDb; + DYNAMICEX_MAPPING *ExMapTable; + UINTN Index; + UINTN Index2; + BOOLEAN Found; + BOOLEAN PeiExMapTableEmpty; + EFI_GUID *GuidTable; + + if (!FeaturePcdGet (PcdPeiFullPcdDatabaseEnable)) { + return EFI_UNSUPPORTED; + } + + ASSERT (Guid !=3D NULL); + + PeiPcdDb =3D GetPcdDatabase (); + + if (PeiPcdDb->ExTokenCount =3D=3D 0) { + PeiExMapTableEmpty =3D TRUE; + } else { + PeiExMapTableEmpty =3D FALSE; + } + + if (PeiExMapTableEmpty) { + return EFI_NOT_FOUND; + } + + ExMapTable =3D (DYNAMICEX_MAPPING *)((UINT8 *)PeiPcdDb + PeiPcdDb->ExMap= TableOffset); + GuidTable =3D (EFI_GUID *)((UINT8 *)PeiPcdDb + PeiPcdDb->GuidTableOffse= t); + + if (*Guid =3D=3D NULL) { + // + // return the first Token Space Guid. + // + *Guid =3D GuidTable + ExMapTable[0].ExGuidIndex; + return EFI_SUCCESS; + } + + MatchGuid =3D ScanGuid (GuidTable, PeiPcdDb->GuidTableCount * sizeof (Gu= idTable[0]), *Guid); + + if (MatchGuid =3D=3D NULL) { + return EFI_NOT_FOUND; + } + + GuidTableIdx =3D MatchGuid - GuidTable; + + Found =3D FALSE; + for (Index =3D 0; Index < PeiPcdDb->ExTokenCount; Index++) { + if (ExMapTable[Index].ExGuidIndex =3D=3D GuidTableIdx) { + Found =3D TRUE; + break; + } + } + + if (Found) { + Index++; + for ( ; Index < PeiPcdDb->ExTokenCount; Index++ ) { + if (ExMapTable[Index].ExGuidIndex !=3D GuidTableIdx) { + Found =3D FALSE; + for (Index2 =3D 0; Index2 < Index; Index2++) { + if (ExMapTable[Index2].ExGuidIndex =3D=3D ExMapTable[Index].ExGu= idIndex) { + // + // This token namespace should have been found and output at p= receding getting. + // + Found =3D TRUE; + break; + } + } + + if (!Found) { + *Guid =3D (EFI_GUID *)((UINT8 *)PeiPcdDb + PeiPcdDb->GuidTableOf= fset) + ExMapTable[Index].ExGuidIndex; + return EFI_SUCCESS; + } + } + } + + *Guid =3D NULL; + } + + return EFI_NOT_FOUND; +} + +/** + Get PCD value's size for POINTER type PCD. + + The POINTER type PCD's value will be stored into a buffer in specified s= ize. + The max size of this PCD's value is described in PCD's definition in DEC= file. + + @param LocalTokenNumberTableIdx Index of PCD token number in PCD token t= able + @param MaxSize Maximum size of PCD's value + @param Database Pcd database in PEI phase. + + @return PCD value's size for POINTER type PCD. + +**/ +UINTN +GetPtrTypeSize ( + IN UINTN LocalTokenNumberTableIdx, + OUT UINTN *MaxSize, + IN PEI_PCD_DATABASE *Database + ) +{ + INTN SizeTableIdx; + UINTN LocalTokenNumber; + SIZE_INFO *SizeTable; + + SizeTableIdx =3D GetSizeTableIndex (LocalTokenNumberTableIdx, Database); + + LocalTokenNumber =3D *((UINT32 *)((UINT8 *)Database + Database->LocalTok= enNumberTableOffset) + LocalTokenNumberTableIdx); + + ASSERT ((LocalTokenNumber & PCD_DATUM_TYPE_ALL_SET) =3D=3D PCD_DATUM_TYP= E_POINTER); + + SizeTable =3D (SIZE_INFO *)((UINT8 *)Database + Database->SizeTableOffse= t); + + *MaxSize =3D SizeTable[SizeTableIdx]; + // + // SizeTable only contain record for PCD_DATUM_TYPE_POINTER type + // PCD entry. + // + if ((LocalTokenNumber & PCD_TYPE_VPD) !=3D 0) { + // + // We have only two entry for VPD enabled PCD entry: + // 1) MAX Size. + // 2) Current Size + // We consider current size is equal to MAX size. + // + return *MaxSize; + } else { + // + // We have only two entry for Non-Sku enabled PCD entry: + // 1) MAX SIZE + // 2) Current Size + // + return SizeTable[SizeTableIdx + 1]; + } +} + +/** + Set PCD value's size for POINTER type PCD. + + The POINTER type PCD's value will be stored into a buffer in specified s= ize. + The max size of this PCD's value is described in PCD's definition in DEC= file. + + @param LocalTokenNumberTableIdx Index of PCD token number in PCD token t= able + @param CurrentSize Maximum size of PCD's value + @param Database Pcd database in PEI phase. + + @retval TRUE Success to set PCD's value size, which is not exceed maxim= um size + @retval FALSE Fail to set PCD's value size, which maybe exceed maximum s= ize + +**/ +BOOLEAN +SetPtrTypeSize ( + IN UINTN LocalTokenNumberTableIdx, + IN OUT UINTN *CurrentSize, + IN PEI_PCD_DATABASE *Database + ) +{ + INTN SizeTableIdx; + UINTN LocalTokenNumber; + SIZE_INFO *SizeTable; + UINTN MaxSize; + + SizeTableIdx =3D GetSizeTableIndex (LocalTokenNumberTableIdx, Database); + + LocalTokenNumber =3D *((UINT32 *)((UINT8 *)Database + Database->LocalTok= enNumberTableOffset) + LocalTokenNumberTableIdx); + + ASSERT ((LocalTokenNumber & PCD_DATUM_TYPE_ALL_SET) =3D=3D PCD_DATUM_TYP= E_POINTER); + + SizeTable =3D (SIZE_INFO *)((UINT8 *)Database + Database->SizeTableOffse= t); + + MaxSize =3D SizeTable[SizeTableIdx]; + // + // SizeTable only contain record for PCD_DATUM_TYPE_POINTER type + // PCD entry. + // + if ((LocalTokenNumber & PCD_TYPE_VPD) !=3D 0) { + // + // We shouldn't come here as we don't support SET for VPD + // + ASSERT (FALSE); + return FALSE; + } else { + if ((*CurrentSize > MaxSize) || + (*CurrentSize =3D=3D MAX_ADDRESS)) + { + *CurrentSize =3D MaxSize; + return FALSE; + } + + // + // We have only two entry for Non-Sku enabled PCD entry: + // 1) MAX SIZE + // 2) Current Size + // + SizeTable[SizeTableIdx + 1] =3D (SIZE_INFO)*CurrentSize; + return TRUE; + } +} diff --git a/Platform/AMD/VanGoghBoard/Override/edk2/MdeModulePkg/Universal= /PCD/Pei/Pcd.inf b/Platform/AMD/VanGoghBoard/Override/edk2/MdeModulePkg/Uni= versal/PCD/Pei/Pcd.inf new file mode 100644 index 0000000000..204f08b958 --- /dev/null +++ b/Platform/AMD/VanGoghBoard/Override/edk2/MdeModulePkg/Universal/PCD/Pe= i/Pcd.inf @@ -0,0 +1,368 @@ +## @file +# PCD PEI Module INF file +# +# Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +## @file +# PCD PEIM produces PCD database to manage all dynamic PCD in PEI phase an= d install Pcd Ppi service. +# +# This version PCD PEIM depends on the external PCD database binary file, = not built in PCD data base. +# There are two PCD PPIs as follows: +# 1) PCD_PPI +# It is EDKII implementation which support Dynamic/DynamicEx Pcds. +# 2) EFI_PEI_PCD_PPI +# It is defined by PI specification 1.2, Vol 3 which only support dyn= amicEx +# type Pcd. +# For dynamicEx type PCD, it is compatible between PCD_PPI and EFI_PEI_PCD= _PPI. +# PCD PEIM driver will produce above two PPIs at same time. +# +# PCD database is generated as the separate binary image at build time. Th= e binary image +# will be intergrated into Firmware volume together with PCD driver. +# +# ////////////////////////////////////////////////////////////////////////= //////// +# // = // +# // Introduction of PCD database = // +# // = // +# ////////////////////////////////////////////////////////////////////////= //////// +# +# 1, Introduction +# PCD database hold all dynamic type PCD information. The structure of = PEI PCD +# database is generated by build tools according to dynamic PCD usage f= or +# specified platform. +# +# 2, Dynamic Type PCD +# Dynamic type PCD is used for the configuration/setting which value is= determined +# dynamic. In contrast, the value of static type PCD (FeatureFlag, Fixe= dPcd, +# PatchablePcd) is fixed in final generated FD image in build time. +# +# 2.1 The "dynamic" determination means one of below cases: +# a) The PCD setting value is produced by someone driver and consumed= by +# other driver in execution time. +# b) The PCD setting value is set/get by user from FrontPage. +# c) The PCD setting value is produced by platform OEM vendor in spec= ified area. +# +# 2.2 According to module distribution way, dynamic PCD could be classf= ied as: +# a) Dynamic: +# If module is released in source code and will be built with plat= form +# DSC, the dynamic PCD used by this module can be accessed as: +# PcdGetxx(PcdSampleDynamicPcd); +# In building platform, build tools will translate PcdSampleDynami= cPcd to +# pair of {Token Space Guid: Token Number} for this PCD. +# b) DynamicEx: +# If module is release as binary and will not pariticpate platform= building, +# the dynamic PCD used by this module need be accessed as: +# PcdGetxxEx(gEfiMyTokenspaceGuid, PcdSampleDynamicPcd) +# Developer need explicity gives {Token Space Guid:Token Number} a= s parameter +# in writting source code. +# +# 2.3 According to PCD value's storage method, dynamic PCD could be cla= ssfied as: +# a) Default Storage: +# - The PCD value is stored in PCD database maintained by PCD driv= er in boot +# time memory. +# - This type is used for communication between PEIM/DXE driver, D= XE/DXE +# driver. But all set/get value will be losted after boot-time m= emory +# is turn off. +# - [PcdsDynamicDefault] is used as section name for this type PCD= in +# platform DSC file. [PcdsDynamicExDefault] is used for dynamicE= x type PCD. +# +# b) Variable Storage: +# - The PCD value is stored in variable area. +# - As default storage type, this type PCD could be used for PEI/D= XE driver +# communication. But beside it, this type PCD could also be used= to store +# the value associate with a HII setting via variable interface. +# - In PEI phase, the PCD value could only be got but can not be s= et due +# to variable area is readonly. +# - [PcdsDynamicHii] is used as section name for this type PCD in = platform +# DSC file. [PcdsDynamicExHii] is for dynamicEx type PCD. +# +# c) OEM specificed storage area: +# - The PCD value is stored in OEM specified area which base addre= ss is +# specified by PCD setting - PcdVpdBaseAddress64 or PcdVpdBaseAd= dress. +# - The area is read only for PEI and DXE phase. +# - [PcdsDynamicVpd] is used as section name for this type PCD in = platform +# DSC file. [PcdsDynamicExVpd] is for dynamicex type PCD. +# +# 2.4 When and how to use dynamic PCD +# Module developer do not care the used PCD is dynamic or static when= writting +# source code/INF. Dynamic PCD and dynamic type is pointed by platfor= m integrator +# in platform DSC file. Please ref section 2.3 to get matching betwee= n dynamic +# PCD type and section name in DSC file. +# +# 3, PCD database: +# Although dynamic PCD could be in different storage type as above desc= ription, +# but the basic information and default value for all dynamic PCD is ho= ld +# by PCD database maintained by PEI/DXE driver. +# +# As the whole EFI BIOS boot path is divided into PEI/DXE phase, the PC= D database +# also is divided into Pei/Dxe database maintaied by PcdPeim/PcdDxe dri= ver separatly. +# To make PcdPeim's driver image smaller, PEI PCD database only hold al= l dynamic +# PCD information used in PEI phase or use in both PEI/DXE phase. And D= XE PCD +# database contains all PCDs used in PEI/DXE phase in memory. +# +# Build tool will generate PCD database into the separate binary file f= or +# PEI/DXE PCD driver according to dynamic PCD section in platform DSC f= ile. +# +# 3.1 PcdPeim and PcdDxe +# PEI PCD database is maintained by PcdPeim driver run from flash. Pc= dPeim driver +# build guid hob in temporary memory and copy the binary data base fr= om flash +# to temporary memory for PEI PCD database. +# DXE PCD database is maintained by PcdDxe driver.At entry point of P= cdDxe driver, +# a new PCD database is allocated in boot-time memory which including= all +# PEI PCD and DXE PCD entry. +# +# Pcd driver should run as early as possible before any other driver = access +# dynamic PCD's value. PEI/DXE "Apriori File" mechanism make it possi= ble by +# making PcdPeim/PcdDxe as first dispatching driver in PEI/DXE phase. +# +# 3.2 Token space Guid/Token number, Platform token, Local token number +# Dynamic PCD +# +-----------+ +---------+ +# |TokenSpace | |Platform | +# | Guid | build tool | Token | +# | + +-------------->| Number | +# | Token | +---------+`._ +# | Number | `. +# +-----------+ `. +------+ +# `-|Local | +# |Token | +# DynamicEx PCD ,-|Number| +# +-----------+ ,-' +------+ +# |TokenSpace | ,-' +# | Guid | _,-' +# | + +.' +# | Token | +# | Number | +# +-----------+ +# +# +# 3.2.1 Pair of Token space guid + Token number +# Any type PCD is identified by pair of "TokenSpaceGuid + TokeNumbe= r". But it +# is not easy maintained by PCD driver, and hashed token number wil= l make +# searching slowly. +# +# 3.2.2 Platform Token Number +# "Platform token number" concept is introduced for mapping to a pa= ir of +# "TokenSpaceGuid + TokenNumber". The platform token number is gene= rated by +# build tool in autogen.h and all of them are continual in a platfo= rm scope +# started from 1.(0 meaning invalid internal token number) +# With auto-generated "platform token number", PcdGet(PcdSampleDyna= micPcd) +# in source code is translated to LibPcdGet(_PCD_TOKEN_PcdSampleDyn= amicPcd) +# in autogen.h. +# Notes: The mapping between pair of "tokenspace guid + token numbe= r" and +# "internal token number" need build tool establish, so "platform t= oken number" +# mechanism is not suitable for binary module which use DynamicEx t= ype PCD. +# To access a dynamicEx type PCD, pair of "token space guid/token n= umber" all need +# to be specificed for PcdSet/PcdGet accessing macro. +# +# Platform Token Number is started from 1, and inceased continuous.= From whole +# platform scope, there are two zones: PEI Zone and DXE Zone +# | Platform Token Number +# ----------|------------------------------------------------------= ---------- +# PEI Zone: | 1 ~ PEI_LOCAL_TOKEN_NUMBER +# DXE Zone: | (PEI_LOCAL_TOKEN_NUMBER + 1) ~ (PEI_LOCAL_TOKEN_NUMBE= R + DXE_LOCAL_TOKEN_NUMBER) +# +# 3.2.3 Local Token Number +# To fast searching a PCD entry in PCD database, PCD driver transla= te +# platform token number to local token number via a mapping table. +# For binary DynamicEx type PCD, there is a another mapping table t= o translate +# "token space guid + token number" to local token number directly. +# Local token number is identifier for all internal interface in PC= D PEI/DXE +# driver. +# +# A local token number is a 32-bit value in following meaning: +# 32 ------------- 28 ---------- 24 -------- 0 +# | PCD type mask | Datum Type | Offset | +# +-----------------------------------------+ +# where: +# PCd type mask: indicate Pcd type from following macro: +# PCD_TYPE_DATA +# PCD_TYPE_HII +# PCD_TYPE_VPD +# PCD_TYPE_STRING +# Datum Type : indicate PCD vaue type from following macro: +# PCD_DATUM_TYPE_POINTER +# PCD_DATUM_TYPE_UINT8 +# PCD_DATUM_TYPE_UINT16 +# PCD_DATUM_TYPE_UINT32 +# PCD_DATUM_TYPE_UINT64 +# Offset : indicate the related offset of PCD value in PCD d= atabase array. +# Based on local token number, PCD driver could fast determine PCD t= ype, value +# type and get PCD entry from PCD database. +# +# 3.3 PCD Database binary file +# PCD Database binary file will be created at build time as the stand= alone binary image. +# To understand the binary image layout, PCD Database C structure is = still generated +# as comments by build tools in PCD driver's autogen.h/ +# autogen.c file. In generated C structure, following information is = stored: +# - ExMapTable: This table is used translate a binary dynamicex type = PCD's +# "tokenguid + token" to local token number. +# - LocalTokenNumberTable: +# This table stores all local token number in array, us= e "Internal +# token number" as array index to get PCD entry's offse= t fastly. +# - SizeTable: This table stores the size information for all PCD en= try. +# - GuidTable: This table stores guid value for DynamicEx's token sp= ace, +# HII type PCD's variable GUID. +# - SkuIdTable: TBD +# - SystemSkuId: TBD +# - PCD value structure: +# Every PCD has a value record in PCD database. For dif= ferent +# datum type PCD has different record structure which w= ill be +# introduced in 3.3.1 +# +# In a PCD database structure, there are two major area: Init and UnI= nit. +# Init area is use stored above PCD internal structure such as ExMapT= able, +# LocalTokenNumberTable etc and the (default) value of PCD which has = default +# value specified in platform DSC file. +# Unint area is used stored the value of PCD which has no default val= ue in +# platform DSC file, the value of NULL, 0 specified in platform DSC f= ile can +# be seemed as "no default value". +# +# 3.3.1 Simple Sample PCD Database C Structure +# A general sample of PCD database structue is as follows: +# typedef struct _PCD_DATABASE { +# typedef struct _PCD_DATABASE_INIT { +# //=3D=3D=3D=3D=3D Following is PCD database internal maintain= structures +# DYNAMICEX_MAPPING ExMapTable[PEI_EXMAPPING_TABLE_SIZE]; +# UINT32 LocalTokenNumberTable[PEI_LOCAL_TOKEN_NUMBE= R_TABLE_SIZE]; +# GUID GuidTable[PEI_GUID_TABLE_SIZE]; +# SIZE_INFO SizeTable[PEI_SIZE_TABLE_SIZE]; +# UINT8 SkuIdTable[PEI_SKUID_TABLE_SIZE]; +# SKU_ID SystemSkuId; +# +# //=3D=3D=3D=3D=3D Following is value structure for PCD with d= efault value +# .... +# .... +# .... +# } Init; +# typedef struct _PCD_DATABSE_UNINIT { +# //=3D=3D=3D=3D Following is value structure for PCD without d= efault value +# .... +# .... +# } UnInit; +# } +# +# 3.3.2 PCD value structure in PCD database C structure +# The value's structure is generated by build tool in PCD database = C structure. +# The PCDs in different datum type has different value structure. +# +# 3.3.2.1 UINT8/UINT16/UINT32/UINT64 datum type PCD +# The C structure for these datum type PCD is just a UINT8/UINT16= /UINT32/UINT64 +# data member in PCD database, For example: +# UINT16 PcdHardwareErrorRecordLevel_d3705011_bc19_4af7_be16_f68= 030378c15_VariableDefault_0; +# Above structure is generated by build tool, the member name is = "PcdCName_Guidvalue" +# Member type is UINT16 according to PcdHardwareErrorRecordLevel = declaration +# in DEC file. +# +# 3.3.2.2 VOID* datum type PCD +# The value of VOID* datum type PCD is a UINT8/UINT16 array in PC= D database. +# +# 3.3.2.2.1 VOID* - string type +# If the default value for VOID* datum type PCD like L"xxx", th= e PCD is +# used for unicode string, and C structure of this datum type P= CD is +# UINT16 string array in PCD database, for example: +# UINT16 StringTable[29]; +# The number of 29 in above sample is max size of a unicode str= ing. +# +# If the default value for VOID* datum type PCD like "xxx", the= PCD is +# used for ascii string, and C structure of this datum type PCD= is +# UINT8 string array in PCD database, for example: +# UINT8 StringTable[20]; +# The number of 20 in above sample is max size of a ascii strin= g. +# +# 3.3.2.2.2 VOID* - byte array +# If the default value of VOID* datum type PCD like {'0x29', '0= x01', '0xf2'} +# the PCD is used for byte array. The generated structrue is sa= me as +# above ascii string table, +# UINT8 StringTable[13]; +# The number of 13 in above sample is max size of byte array. +# +# 3.3.3 Some utility structures in PCD Database +# 3.3.3.1 GuidTable +# GuidTable array is used to store all related GUID value in PCD = database: +# - Variable GUID for HII type PCD +# - Token space GUID for dynamicex type PCD +# +# Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +# +## + +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D PcdPeim + MODULE_UNI_FILE =3D PcdPeim.uni + FILE_GUID =3D 9B3ADA4F-AE56-4c24-8DEA-F03B7558AE50 + MODULE_TYPE =3D PEIM + VERSION_STRING =3D 4.0 + PCD_IS_DRIVER =3D PEI_PCD_DRIVER + ENTRY_POINT =3D PcdPeimInit + +# +# The following information is for reference only and not required by the = build tools. +# +# VALID_ARCHITECTURES =3D IA32 X64 EBC (EBC is for build only) +# + +[Sources] + Service.c + Service.h + Pcd.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + ChachaniBoardPkg/Project.dec + Override/edk2/Fsp2WrapperPkg/Fsp2WrapperPkg.dec + +[LibraryClasses] + BaseMemoryLib + PcdLib + PeiServicesLib + HobLib + BaseLib + PeimEntryPoint + DebugLib + MemoryAllocationLib + +[Guids] + ## PRODUCES ## HOB + ## SOMETIMES_CONSUMES ## HOB + gPcdDataBaseHobGuid + gPcdDataBaseSignatureGuid ## CONSUMES ## GUID # PC= D database signature GUID. + gEfiMdeModulePkgTokenSpaceGuid ## SOMETIMES_CONSUMES ## = GUID + gEfiAmdAgesaModulePkgTokenSpaceGuid + gEfiAmdAgesaPkgTokenSpaceGuid + gAmdCpmPkgTokenSpaceGuid + gAmdFspPkgGuid + +[Ppis] + gEfiPeiReadOnlyVariable2PpiGuid ## SOMETIMES_CONSUMES + gPcdPpiGuid ## PRODUCES + gEfiPeiPcdPpiGuid ## PRODUCES + gGetPcdInfoPpiGuid ## SOMETIMES_PRODUCES + gEfiGetPcdInfoPpiGuid ## SOMETIMES_PRODUCES + gEfiEndOfPeiSignalPpiGuid ## NOTIFY + gFspEfiPeiPcdPpiGuid ## SOMETIMES_PRODUCES + gFspEfiGetPcdInfoPpiGuid ## SOMETIMES_PRODUCES + +[FeaturePcd] + gEfiMdeModulePkgTokenSpaceGuid.PcdPeiFullPcdDatabaseEnable ## CONSUMES + +[Pcd] + gEfiMdeModulePkgTokenSpaceGuid.PcdVpdBaseAddress ## SOMETIMES_CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdVpdBaseAddress64 ## SOMETIMES_CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdMaxPeiPcdCallBackNumberPerPcdEntry ## = SOMETIMES_CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdNvStoreDefaultValueBuffer ## SOMETIMES= _CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdSetNvStoreDefaultId ## CONSUMES + gIntelFsp2WrapperTokenSpaceGuid.PcdFspModeSelection + +[Depex] + TRUE + +[UserExtensions.TianoCore."ExtraFiles"] + PcdPeimExtra.uni diff --git a/Platform/AMD/VanGoghBoard/Override/edk2/MdePkg/Include/Registe= r/Intel/SmramSaveStateMap.h b/Platform/AMD/VanGoghBoard/Override/edk2/MdePk= g/Include/Register/Intel/SmramSaveStateMap.h new file mode 100644 index 0000000000..05487d75e9 --- /dev/null +++ b/Platform/AMD/VanGoghBoard/Override/edk2/MdePkg/Include/Register/Intel= /SmramSaveStateMap.h @@ -0,0 +1,324 @@ +/** @file +SMRAM Save State Map Definitions. + +SMRAM Save State Map definitions based on contents of the +Intel(R) 64 and IA-32 Architectures Software Developer's Manual + Volume 3C, Section 34.4 SMRAM + Volume 3C, Section 34.5 SMI Handler Execution Environment + Volume 3C, Section 34.7 Managing Synchronous and Asynchronous SMIs + +Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.
+Copyright (c) 2015 - 2019, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef INTEL_SMRAM_SAVE_STATE_MAP_H____ +#define INTEL_SMRAM_SAVE_STATE_MAP_H____ +#define AMD_CPU 1 +/// +/// Default SMBASE address +/// +#define SMM_DEFAULT_SMBASE 0x30000 + +/// +/// Offset of SMM handler from SMBASE +/// +#define SMM_HANDLER_OFFSET 0x8000 + +/// +/// Offset of SMRAM Save State Map from SMBASE +/// +#if AMD_CPU +#define SMRAM_SAVE_STATE_MAP_OFFSET 0xfe00 +#else +#define SMRAM_SAVE_STATE_MAP_OFFSET 0xfc00 +#endif + +#pragma pack (1) + +#if AMD_CPU +/// +/// CPU save-state strcuture for AMD64 Architecture +/// +typedef struct { + UINT8 Reserved[0xF8]; // FE00h - FEF7h , Reserved, 248 Bytes, -- + UINT32 SMBASE; // FEF8h, SMBASE, Doubleword, Read/Write + UINT32 SMMRevId; // FEFCh, SMM-Revision identifier, Doubleword= , Read-Only + UINT16 IORestart; // FF00h, I/O Instruction Restart, Word, Read= /Write + UINT16 AutoHALTRestart; // FF02h, Auti-Halt Restart, Word, Read/Write + UINT8 Reserved1[0x84]; // FF04h - FF87h, Reserved, 132 Bytes -- + UINT32 GdtBase; // FF88h, GDT Base, Doubleword, Read-Only + UINT64 Reserved2; // FF8Ch - FF93h, Quadword, -- + UINT32 IDTBase; // FF94h, IDT Base, Doubleword, Read-Only + UINT8 Reserved3[0x10]; // FF98 - FFA7h, Reserved, 16Bytes, -- + UINT32 _ES; // FFA8h, ES, Doubleword, Read-Only + UINT32 _CS; // FFACh, CS, Doubleword, Read-Only + UINT32 _SS; // FFB0h, SS, Doubleword, Read-Only + UINT32 _DS; // FFB4h, DS, Doubleword, Read-Only + UINT32 _FS; // FFB8h, FS, Doubleword, Read-Only + UINT32 _GS; // FFBCh, GS, Doubleword, Read-Only + UINT32 LDTBase; // FFC0h, LDT Base, Doubleword, Read-Only + UINT32 _TR; // FFC4h, TR, Doubleword, Read-Only + UINT32 _DR7; // FFC8h, DR7, Doubleword, Read-Only + UINT32 _DR6; // FFCCh, DR6, Doubleword, Read-Only + UINT32 _EAX; // FFD0h, EAX, Doubleword, Read/Write + UINT32 _ECX; // FFD4h, ECX, Doubleword, Read/Write + UINT32 _EDX; // FFD8h, EDX, Doubleword, Read/Write + UINT32 _EBX; // FFDCh, EBX, Doubleword, Read/Write + UINT32 _ESP; // FFE0h, ESP, Doubleword, Read/Write + UINT32 _EBP; // FFE4h, EBP, Doubleword, Read/Write + UINT32 _ESI; // FFE8h, ESI, Doubleword, Read/Write + UINT32 _EDI; // FFECh, EDI, Doubleword, Read/Write + UINT32 _EIP; // FFF0h, EIP, Doubleword, Read/Write + UINT32 _EFLAGS; // FFF4h, EFLAGS, Doubleword, Read/Write + UINT32 _CR3; // FFF8h, CR3, Doubleword, Read/Write + UINT32 _CR0; // FFFCh, CR0, Doubleword, Read/Write +} SMRAM_SAVE_STATE_MAP32; + +typedef struct { + UINT16 _ES; // FE00h, ES Selector, Word, Read-Only + UINT16 ESAttributes; // FE02h, ES Attributes, Word, Read-Only + UINT32 ESLimit; // FE04h, ES Limit, Doubleword, Read-Only + UINT64 ESBase; // FE08h, ES Base, Quadword, Read-Only + UINT16 _CS; // FE10h, CS Selector, Word, Read-Only + UINT16 CSAttributes; // FE12h, CS Attributes, Word, Read-Only + UINT32 CSLimit; // FE14h, CS Limit, Doubleword, Read-Only + UINT64 CSBase; // FE18h, CS Base, Quadword, Read-Only + UINT16 _SS; // FE20h, SS Selector, Word, Read-Only + UINT16 SSAttributes; // FE22h, SS Attributes, Word, Read-Only + UINT32 SSLimit; // FE24h, SS Limit, Doubleword, Read-Only + UINT64 SSBase; // FE28h, SS Base, Quadword, Read-Only + UINT16 _DS; // FE30h, DS Selector, Word, Read-Only + UINT16 DSAttributes; // FE32h, DS Attributes, Word, Read-Only + UINT32 DSLimit; // FE34h, DS Limit, Doubleword, Read-Only + UINT64 DSBase; // FE38h, DS Base, Quadword, Read-Only + UINT16 _FS; // FE40h, FS Selector, Word, Read-Only + UINT16 FSAttributes; // FE42h, FS Attributes, Word, Read-Only + UINT32 FSLimit; // FE44h, FS Limit, Doubleword, Read-Only + UINT64 FSBase; // FE48h, FS Base, Quadword, Read-Only + UINT16 _GS; // FE50h, GS Selector, Word, Read-Only + UINT16 GSAttributes; // FE52h, GS Attributes, Word, Read-Only + UINT32 GSLimit; // FE54h, GS Limit, Doubleword, Read-Only + UINT64 GSBase; // FE58h, GS Base, Quadword, Read-Only + UINT8 Reserved1[4]; // FE60h - FE63h, GDTR Reserved, 4 Bytes,= Read-Only + UINT16 GdtrLimit; // FE64h, GDTR Limit, Word, Read-Only + UINT8 Reserved2[2]; // FE66h - FE67h, Reserved, 2 Bytes, Read= -Only + // UINT64 GDTR_Base; // FE68h, GDTR Base, Quadword, Read-On= ly + UINT32 GdtrBaseLoDword; + UINT32 GdtrBaseHiDword; + UINT16 LdtrSelector; // FE70h, LDTR Selector, Word, Read-Only + UINT16 LdtrAttributes; // FE72h, LDTR Attributes, Word, Read-Only + UINT32 LdtrLimit; // FE74h, LDTR Limit, Doubleword, Read-On= ly + // UINT64 LDTR_Base; // FE78h, LDTR Base, Quadword, Read-On= ly + UINT32 LdtrBaseLoDword; + UINT32 LdtrBaseHiDword; + UINT8 Reserved3[4]; // FE80h - FE83h (PID: 24593 (PUB) 3.20 p= .279 has a technical errors), IDTR Reserved, 4 Bytes, Read-Only + UINT16 IdtrLimit; // FE84h, IDTR Limit, Word, Read-Only + UINT8 Reserved4[2]; // FE86h - FE87h (PID: 24593 (PUB) 3.20 p= .279 has a technical errors), IDTR Reserved, 2 Bytes, Read-Only + // UINT64 IDTR_Base; // FE88h, IDTR Base, Quadword, Read-On= ly + UINT32 IdtrBaseLoDword; + UINT32 IdtrBaseHiDword; + UINT16 TrSelector; // FE90h, TR Selector, Word, Read-Only + UINT16 TrAttributes; // FE92h, TR Attributes, Word, Read-Only + UINT32 TrLimit; // FE94h, TR Limit, Doubleword, Read-Only + UINT64 TrBase; // FE98h, TR Base, Quadword, Read-Only + UINT64 IO_RESTART_RIP; // FEA0h, I/O Instruction Restart RIP, Q= uadword, Read-Only + UINT64 IO_RESTART_RCX; // FEA8h, I/O Instruction Restart RCX, Q= uadword, Read-Only + UINT64 IO_RESTART_RSI; // FEB0h, I/O Instruction Restart RSI, Q= uadword, Read-Only + UINT64 IO_RESTART_RDI; // FEB8h, I/O Instruction Restart RDI, Q= uadword, Read-Only + UINT32 SMM_IO_TRAP; // FEC0h, I/O Instruction Restart Dword = SMMFEC0 [SMM IO Trap Offset], Read-Only + UINT32 LocalSmiStatus; // FEC4h, SMMFEC4 [Local SMI Status], Do= ubleword, Read-Only + UINT8 SMM_IO_RESTART; // FEC8h, SMMFEC8 [SMM IO Restart Byte],= Byte, Read/Write + UINT8 AutoHALTRestart; // FEC9h, SMMFEC9 [Auto Halt Restart Off= set], Byte, Read/Write + UINT8 NMI_MASK; // FECAh, SMMFECA [NMI Mask], Byte, Read= /Write + UINT8 Reserved5[5]; // FECBh - FECFh, Reserved, 5 Bytes, -- + UINT64 EFER; // FED0h, EFER, Quadword, Read-Only + UINT64 SMM_SVM_State; // FED8h, SMMFED8 [SMM SVM State], Read-= Only + UINT64 Guest_VMCB_PHY_ADDR; // FEE0h, Guest VMCB physical address, R= ead-Only + UINT64 SVM_Virtual_INT_CTRL; // FEE8h, SVM Virtual Interrupt Control,= Read-Only + UINT8 Reserved6[12]; // FEF0h - FEFBh, Reserved, 12 Bytes (PI= D: 42300 Family 15h BKDG (NDA) 1.11 p.49 has a technial error), -- + UINT32 SMMRevId; // FEFCh, SMMFEFC [SMM-Revision-Indentif= ier], Doubleword, Read/Write + UINT32 SMBASE; // FF00h, SMMFF00 [SMM Base Address (SMM= _BASE)], Read/Write + UINT8 Reserved7[28]; // FF04h, Reserved, 24 Bytes, -- + UINT64 GuestPAT; // FF20h, Guest PAT, Quadword, Read-Only + UINT64 HostEFER; // FF28h, Host EFER, Quadword, Read-Only + UINT64 HostCR4; // FF30h, Host CR4, Quadword, Read-Only + UINT64 NestedCR3; // FF38h, Nested CR3, Quadword, Read-Only + UINT64 HostCR0; // FF40h, Host CR0, Quadword, Read-Only + UINT64 _CR4; // FF48h, CR4, Quadword, Read-Only + UINT64 _CR3; // FF50h, CR3, Quadword, Read-Only + UINT64 _CR0; // FF58h, CR0, Quadword, Read-Only + UINT64 _DR7; // FF60h, DR7, Quadword, Read-Only + UINT64 _DR6; // FF68h, DR6, Quadword, Read-Only + UINT64 _RFLAGS; // FF70h, RFLAGS, Quadword, Read/Write + UINT64 _RIP; // FF78h, RIP, Quadword, Read/Write + UINT64 _R15; // FF80h, R15, Quadword, Read/Write + UINT64 _R14; // FF88h, R14, Quadword, Read/Write + UINT64 _R13; // FF90h, R13, Quadword, Read/Write + UINT64 _R12; // FF98h, R12, Quadword, Read/Write + UINT64 _R11; // FFA0h, R11, Quadword, Read/Write + UINT64 _R10; // FFA8h, R10, Quadword, Read/Write + UINT64 _R9; // FFB0h, R9, Quadword, Read/Write + UINT64 _R8; // FFB8, R8, Quadword, Read/Write + UINT64 _RDI; // FFC0h, RDI, Quadword, Read/Write + UINT64 _RSI; // FFD8h, RSI, Quadword, Read/Write + UINT64 _RBP; // FFD0h, RBP, Quadword, Read/Write + UINT64 _RSP; // FFE0h, RSP, Quadword, Read/Write + UINT64 _RBX; // FFE0h, RBX, Quadword, Read/Write + UINT64 _RDX; // FFE8h, RDX, Quadword, Read/Write + UINT64 _RCX; // FFF0h, RCX, Quadword, Read/Write + UINT64 _RAX; // FFF8h, RAX, Quadword, Read/Write +} SMRAM_SAVE_STATE_MAP64; +#else +/// +/// 32-bit SMRAM Save State Map +/// +typedef struct { + UINT8 Reserved[0x200]; // 7c00h + // Padded an extra 0x200 bytes so 32-bit and = 64-bit + // SMRAM Save State Maps are the same size + UINT8 Reserved1[0xf8]; // 7e00h + UINT32 SMBASE; // 7ef8h + UINT32 SMMRevId; // 7efch + UINT16 IORestart; // 7f00h + UINT16 AutoHALTRestart; // 7f02h + UINT8 Reserved2[0x9C]; // 7f08h + UINT32 IOMemAddr; // 7fa0h + UINT32 IOMisc; // 7fa4h + UINT32 _ES; // 7fa8h + UINT32 _CS; // 7fach + UINT32 _SS; // 7fb0h + UINT32 _DS; // 7fb4h + UINT32 _FS; // 7fb8h + UINT32 _GS; // 7fbch + UINT32 Reserved3; // 7fc0h + UINT32 _TR; // 7fc4h + UINT32 _DR7; // 7fc8h + UINT32 _DR6; // 7fcch + UINT32 _EAX; // 7fd0h + UINT32 _ECX; // 7fd4h + UINT32 _EDX; // 7fd8h + UINT32 _EBX; // 7fdch + UINT32 _ESP; // 7fe0h + UINT32 _EBP; // 7fe4h + UINT32 _ESI; // 7fe8h + UINT32 _EDI; // 7fech + UINT32 _EIP; // 7ff0h + UINT32 _EFLAGS; // 7ff4h + UINT32 _CR3; // 7ff8h + UINT32 _CR0; // 7ffch +} SMRAM_SAVE_STATE_MAP32; + +/// +/// 64-bit SMRAM Save State Map +/// +typedef struct { + UINT8 Reserved1[0x1d0]; // 7c00h + UINT32 GdtBaseHiDword; // 7dd0h + UINT32 LdtBaseHiDword; // 7dd4h + UINT32 IdtBaseHiDword; // 7dd8h + UINT8 Reserved2[0xc]; // 7ddch + UINT64 IO_EIP; // 7de8h + UINT8 Reserved3[0x50]; // 7df0h + UINT32 _CR4; // 7e40h + UINT8 Reserved4[0x48]; // 7e44h + UINT32 GdtBaseLoDword; // 7e8ch + UINT32 Reserved5; // 7e90h + UINT32 IdtBaseLoDword; // 7e94h + UINT32 Reserved6; // 7e98h + UINT32 LdtBaseLoDword; // 7e9ch + UINT8 Reserved7[0x38]; // 7ea0h + UINT64 EptVmxControl; // 7ed8h + UINT32 EnEptVmxControl; // 7ee0h + UINT8 Reserved8[0x14]; // 7ee4h + UINT32 SMBASE; // 7ef8h + UINT32 SMMRevId; // 7efch + UINT16 IORestart; // 7f00h + UINT16 AutoHALTRestart; // 7f02h + UINT8 Reserved9[0x18]; // 7f04h + UINT64 _R15; // 7f1ch + UINT64 _R14; + UINT64 _R13; + UINT64 _R12; + UINT64 _R11; + UINT64 _R10; + UINT64 _R9; + UINT64 _R8; + UINT64 _RAX; // 7f5ch + UINT64 _RCX; + UINT64 _RDX; + UINT64 _RBX; + UINT64 _RSP; + UINT64 _RBP; + UINT64 _RSI; + UINT64 _RDI; + UINT64 IOMemAddr; // 7f9ch + UINT32 IOMisc; // 7fa4h + UINT32 _ES; // 7fa8h + UINT32 _CS; + UINT32 _SS; + UINT32 _DS; + UINT32 _FS; + UINT32 _GS; + UINT32 _LDTR; // 7fc0h + UINT32 _TR; + UINT64 _DR7; // 7fc8h + UINT64 _DR6; + UINT64 _RIP; // 7fd8h + UINT64 IA32_EFER; // 7fe0h + UINT64 _RFLAGS; // 7fe8h + UINT64 _CR3; // 7ff0h + UINT64 _CR0; // 7ff8h +} SMRAM_SAVE_STATE_MAP64; +#endif + +/// +/// Union of 32-bit and 64-bit SMRAM Save State Maps +/// +typedef union { + SMRAM_SAVE_STATE_MAP32 x86; + SMRAM_SAVE_STATE_MAP64 x64; +} SMRAM_SAVE_STATE_MAP; + +/// +/// Minimum SMM Revision ID that supports IOMisc field in SMRAM Save State= Map +/// +#define SMRAM_SAVE_STATE_MIN_REV_ID_IOMISC 0x30004 + +/// +/// SMRAM Save State Map IOMisc I/O Length Values +/// +#define SMM_IO_LENGTH_BYTE 0x01 +#define SMM_IO_LENGTH_WORD 0x02 +#define SMM_IO_LENGTH_DWORD 0x04 + +/// +/// SMRAM Save State Map IOMisc I/O Instruction Type Values +/// +#define SMM_IO_TYPE_IN_IMMEDIATE 0x9 +#define SMM_IO_TYPE_IN_DX 0x1 +#define SMM_IO_TYPE_OUT_IMMEDIATE 0x8 +#define SMM_IO_TYPE_OUT_DX 0x0 +#define SMM_IO_TYPE_INS 0x3 +#define SMM_IO_TYPE_OUTS 0x2 +#define SMM_IO_TYPE_REP_INS 0x7 +#define SMM_IO_TYPE_REP_OUTS 0x6 + +/// +/// SMRAM Save State Map IOMisc structure +/// +typedef union { + struct { + UINT32 SmiFlag : 1; + UINT32 Length : 3; + UINT32 Type : 4; + UINT32 Reserved1 : 8; + UINT32 Port : 16; + } Bits; + UINT32 Uint32; +} SMRAM_SAVE_STATE_IOMISC; + +#pragma pack () + +#endif -- 2.31.1 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#114522): https://edk2.groups.io/g/devel/message/114522 Mute This Topic: https://groups.io/mt/103971424/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-