From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from NAM12-DM6-obe.outbound.protection.outlook.com (NAM12-DM6-obe.outbound.protection.outlook.com [40.107.243.88]) by mx.groups.io with SMTP id smtpd.web11.2026.1680850704530516337 for ; Thu, 06 Apr 2023 23:58:24 -0700 Authentication-Results: mx.groups.io; dkim=fail reason="body hash did not verify" header.i=@amd.com header.s=selector1 header.b=05YZNQrP; spf=permerror, err=parse error for token &{10 18 %{i}._ip.%{h}._ehlo.%{d}._spf.vali.email}: invalid domain name (domain: amd.com, ip: 40.107.243.88, mailfrom: abdullateef.attar@amd.com) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=A0k3+dHp4sZOS9PDTqegzh1i24NUYOkNTMfDMLmEp3eLLT6HuGwAU9CW7BILPvVjdddxL3eU6fAMdSkhWw1C43DqaISxoHpYjQ570+jFNd3uf15S3ZpYInSJkWxk6VjRFMlcxyUBzV3Dj7k/gWRpjmA7jVjkPlxWKhXfvc+qppExFXXrnQldRbSHWIS9k6LYa2ZBoHrZ8vAEsoukdg2+MK2dLdR6j4U07w7vpiIBiiBddfqVr9qK4/A0oWl8m1ZU4EBCR8/xcosAiBQvwUBmd/hEb3bjFCwuuLJXLVOkhtDkFXw62rfBSjOK8lTh+/AV/12kY1NyoxaUxyOBKEAoow== 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=10b0QcwHiYcCF2IS2Z++PN1c4Wy8C6b3gmYE38tLiB4=; b=VCgBo2jJ4Yw+jDxF5emAYZ7/G1+I3TE/WwNC9U2E06i7r/3+E5bA/96JxBlQogQwbw9njvidXBLpb31f1Vpu5LT7l76nFMvKSWETjJs8EWv5zvnc17wx0oo0khrTeyAt0pAG6XcvPcoLOVxzhuM2mpqrAaHhhTnlZPwwhJoULX/Y1rHmORxfSEQNzRKYvKZobRFo0TpQnMXTXlDxvgDd1PH73HrLw7f5y5fHnuJIf9WhlOrnTGaz7UnIScg30SHn7F/bgycqTYb94ecsnphGrjho6x8JObSCTA+1KjyFvmXljgz0ruk9F7Jzq2zWf9iJiX03PTrurdWZaJTA35PWvw== 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 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amd.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=10b0QcwHiYcCF2IS2Z++PN1c4Wy8C6b3gmYE38tLiB4=; b=05YZNQrPqzomjoTDs/FOJp/05OulQb0eeaE1GiTrJZjVLc1nbZeM42a4Td4IzkFAksIQyGvdArv2yrQvb92to5qB2kZUVKG0fYZr5eiz+2VrdDk2QBHCFxJ1Sk1IBXi6L05PdsVVNAV0pCgMIi1p9LZoHcseoLS+NldcC6+eGSY= Received: from BN9PR03CA0464.namprd03.prod.outlook.com (2603:10b6:408:139::19) by BY5PR12MB4888.namprd12.prod.outlook.com (2603:10b6:a03:1d8::10) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6254.35; Fri, 7 Apr 2023 06:58:20 +0000 Received: from BN8NAM11FT063.eop-nam11.prod.protection.outlook.com (2603:10b6:408:139:cafe::af) by BN9PR03CA0464.outlook.office365.com (2603:10b6:408:139::19) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6277.34 via Frontend Transport; Fri, 7 Apr 2023 06:58:19 +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 (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 Received: from SATLEXMB04.amd.com (165.204.84.17) by BN8NAM11FT063.mail.protection.outlook.com (10.13.177.110) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.20.6298.20 via Frontend Transport; Fri, 7 Apr 2023 06:58:19 +0000 Received: from SATLEXMB05.amd.com (10.181.40.146) 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.2375.34; Fri, 7 Apr 2023 01:58:19 -0500 Received: from SATLEXMB04.amd.com (10.181.40.145) by SATLEXMB05.amd.com (10.181.40.146) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.34; Fri, 7 Apr 2023 01:58:18 -0500 Received: from BLR-LAB-SFW01.amd.com (10.180.168.240) by SATLEXMB04.amd.com (10.181.40.145) with Microsoft SMTP Server id 15.1.2375.34 via Frontend Transport; Fri, 7 Apr 2023 01:58:15 -0500 From: "Abdul Lateef Attar" To: CC: Abdul Lateef Attar , Paul Grimes , Garrett Kirkendall , Abner Chang , Eric Dong , Ray Ni , Rahul Kumar , Gerd Hoffmann , Abdul Lateef Attar Subject: [PATCH v7 3/8] UefiCpuPkg: Implements SmmSmramSaveStateLib library class Date: Fri, 7 Apr 2023 12:27:56 +0530 Message-ID: <8b3901f83d7d8a74954f58f26bf9ef14a1ce9911.1680847286.git.abdattar@amd.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: References: MIME-Version: 1.0 Return-Path: AbdulLateef.Attar@amd.com X-EOPAttributedMessage: 0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: BN8NAM11FT063:EE_|BY5PR12MB4888:EE_ X-MS-Office365-Filtering-Correlation-Id: b687ebbb-7074-4763-c3de-08db37357865 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: pogELecaMwyBjBuYMLGzspw0OYOTkOPWTgsvowA5dZqroIHfBsuxL+JiGNg9Hchjo0AWTSuWO4hNC4aFRK47+8cGymttg4rPYy7X9GDu7E3VjCwO49tSUQmFEDbQj56jgvj7qGQQBVXSFzRv7knrKX5DQqCAlnX1r1EOUxsJAla2FRFrHA4tNe8ZCDJnaSKza1fzmyLHmhoihGI/+78j5yMD5OwFS8buPgNdXEA8Oej7SLb6/4Bynkn4Wq8Motsxov8ucf3IKKqV6FnFzEn5eQDEXlTISXrsXgpS3gX6s9GXId8k31Lmzb745vksiz+EyKYcNXJyW2Y6mpzkNaGTHIm6bPokptVU+/4csFL9ueRUky14bzuHAgi0Ez6KmVSeegs721SEz5g2BwHKsBTUvB/u7rMfMrAietH3v38PAlMABxOtUogcoOWEzvlrX60fJnqndT9YBP8mtYZo9eoW92ZEsDK8jGj7Vn1YeXNtA8sCD/YNwBjQC7+tmeW7cBl27Lk+zcV2YEOqZCKYNbs8pPMwv8brS4lOk9bs/JFEXhBPPNdR3UM52JE977npCWDFicT8mvKACM+75n+TTvQMq695GiAMXh3dZRSTJLAR17dJQGACRRQxN7ZZYrHvd45hy6SNjVTHyKJvBKG++mLT3a2PYJy5GuxXJvxRt6n5b2HF2yiipT8woEpVmVNzyUwibyPmXJBV35C/a8iZPGDpgd6tX4JFpEdaPWwjL+q/UI4C0g6XTn1njsEiNzVhH9F29NpQA1uMPrVkSStzMjO64S3hp1tBfuwXlNvphNr4F/Q= X-Forefront-Antispam-Report: CIP:165.204.84.17;CTRY:US;LANG:en;SCL:1;SRV:;IPV:CAL;SFV:NSPM;H:SATLEXMB04.amd.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230028)(4636009)(136003)(39860400002)(346002)(396003)(376002)(451199021)(40470700004)(46966006)(36840700001)(478600001)(54906003)(316002)(6916009)(8676002)(70206006)(70586007)(82740400003)(426003)(26005)(40460700003)(186003)(2616005)(336012)(7696005)(47076005)(36756003)(83380400001)(2906002)(6666004)(82310400005)(81166007)(4326008)(36860700001)(966005)(30864003)(356005)(41300700001)(8936002)(40480700001)(5660300002)(213903007)(36900700001);DIR:OUT;SFP:1101; X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 07 Apr 2023 06:58:19.5318 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: b687ebbb-7074-4763-c3de-08db37357865 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: BN8NAM11FT063.eop-nam11.prod.protection.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: BY5PR12MB4888 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain From: Abdul Lateef Attar BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=3D4182 Implements SmmSmramSaveStateLib Library class for AMD cpu family. Cc: Paul Grimes Cc: Garrett Kirkendall Cc: Abner Chang Cc: Eric Dong Cc: Ray Ni Cc: Rahul Kumar Cc: Gerd Hoffmann Signed-off-by: Abdul Lateef Attar Reviewed-by: Abner Chang --- UefiCpuPkg/UefiCpuPkg.dsc | 3 + .../AmdSmmSmramSaveStateLib.inf | 28 ++ .../SmmSmramSaveStateLib/SmramSaveState.h | 101 ++++++ .../SmmSmramSaveStateLib/AmdSmramSaveState.c | 318 ++++++++++++++++++ .../SmramSaveStateCommon.c | 124 +++++++ 5 files changed, 574 insertions(+) create mode 100644 UefiCpuPkg/Library/SmmSmramSaveStateLib/AmdSmmSmramSave= StateLib.inf create mode 100644 UefiCpuPkg/Library/SmmSmramSaveStateLib/SmramSaveState.= h create mode 100644 UefiCpuPkg/Library/SmmSmramSaveStateLib/AmdSmramSaveSta= te.c create mode 100644 UefiCpuPkg/Library/SmmSmramSaveStateLib/SmramSaveStateC= ommon.c diff --git a/UefiCpuPkg/UefiCpuPkg.dsc b/UefiCpuPkg/UefiCpuPkg.dsc index d85d56916f2c..c33059cd3209 100644 --- a/UefiCpuPkg/UefiCpuPkg.dsc +++ b/UefiCpuPkg/UefiCpuPkg.dsc @@ -2,6 +2,7 @@ # UefiCpuPkg Package # # Copyright (c) 2007 - 2022, Intel Corporation. All rights reserved.
+# Copyright (C) 2023 Advanced Micro Devices, Inc. All rights reserved. # # SPDX-License-Identifier: BSD-2-Clause-Patent # @@ -100,6 +101,7 @@ [LibraryClasses.common.DXE_SMM_DRIVER] MemoryAllocationLib|MdePkg/Library/SmmMemoryAllocationLib/SmmMemoryAlloc= ationLib.inf HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmCpuE= xceptionHandlerLib.inf + SmmSmramSaveStateLib|UefiCpuPkg/Library/SmmSmramSaveStateLib/AmdSmmSmram= SaveStateLib.inf =20 [LibraryClasses.common.MM_STANDALONE] MmServicesTableLib|MdePkg/Library/StandaloneMmServicesTableLib/Standalon= eMmServicesTableLib.inf @@ -184,6 +186,7 @@ [Components.IA32, Components.X64] UnitTestResultReportLib|UnitTestFrameworkPkg/Library/UnitTestResultR= eportLib/UnitTestResultReportLibConOut.inf } + UefiCpuPkg/Library/SmmSmramSaveStateLib/AmdSmmSmramSaveStateLib.inf =20 [Components.X64] UefiCpuPkg/Library/CpuExceptionHandlerLib/UnitTest/DxeCpuExceptionHandle= rLibUnitTest.inf diff --git a/UefiCpuPkg/Library/SmmSmramSaveStateLib/AmdSmmSmramSaveStateLi= b.inf b/UefiCpuPkg/Library/SmmSmramSaveStateLib/AmdSmmSmramSaveStateLib.inf new file mode 100644 index 000000000000..91f8927e0419 --- /dev/null +++ b/UefiCpuPkg/Library/SmmSmramSaveStateLib/AmdSmmSmramSaveStateLib.inf @@ -0,0 +1,28 @@ +## @file +# SMM Smram save state service lib. +# +# This is SMM Smram save state service lib that provide service to read an= d +# save savestate area registers. +# +# Copyright (C) 2023 Advanced Micro Devices, Inc. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION =3D 1.29 + BASE_NAME =3D AmdSmmSmramSaveStateLib + FILE_GUID =3D FB7D0A60-E8D4-4EFA-90AA-B357BC569879 + MODULE_TYPE =3D DXE_SMM_DRIVER + VERSION_STRING =3D 1.0 + LIBRARY_CLASS =3D SmmSmramSaveStateLib + +[Sources] + SmramSaveState.h + SmramSaveStateCommon.c + AmdSmramSaveState.c + +[Packages] + MdePkg/MdePkg.dec + UefiCpuPkg/UefiCpuPkg.dec diff --git a/UefiCpuPkg/Library/SmmSmramSaveStateLib/SmramSaveState.h b/Uef= iCpuPkg/Library/SmmSmramSaveStateLib/SmramSaveState.h new file mode 100644 index 000000000000..6c424e3e36e9 --- /dev/null +++ b/UefiCpuPkg/Library/SmmSmramSaveStateLib/SmramSaveState.h @@ -0,0 +1,101 @@ +/** @file + SMRAM Save State Map header file. + + Copyright (c) 2010 - 2019, Intel Corporation. All rights reserved.
+ Copyright (C) 2023 Advanced Micro Devices, Inc. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef SMRAM_SAVESTATE_H_ +#define SMRAM_SAVESTATE_H_ + +#include +#include +#include +#include +#include +#include + +// EFER register LMA bit +#define LMA BIT10 + +// Macro used to simplify the lookup table entries of type CPU_SMM_SAVE_ST= ATE_REGISTER_RANGE +#define SMM_REGISTER_RANGE(Start, End) { Start, End, End - Start + 1 } + +#define SMM_SAVE_STATE_REGISTER_MAX_INDEX 2 + +// Structure used to describe a range of registers +typedef struct { + EFI_SMM_SAVE_STATE_REGISTER Start; + EFI_SMM_SAVE_STATE_REGISTER End; + UINTN Length; +} CPU_SMM_SAVE_STATE_REGISTER_RANGE; + +// Structure used to build a lookup table to retrieve the widths and offse= ts +// associated with each supported EFI_SMM_SAVE_STATE_REGISTER value + +typedef struct { + UINT8 Width32; + UINT8 Width64; + UINT16 Offset32; + UINT16 Offset64Lo; + UINT16 Offset64Hi; + BOOLEAN Writeable; +} CPU_SMM_SAVE_STATE_LOOKUP_ENTRY; + +/** + Returns LMA value of the Processor. + + @param[in] VOID + + @retval UINT8 returns LMA bit value. +**/ +UINT8 +SmramSaveStateGetRegisterLma ( + VOID + ); + +/** + Read information from the CPU save state. + + @param Register Specifies the CPU register to read form the save state= . + + @retval 0 Register is not valid + @retval >0 Index into mSmmSmramCpuWidthOffset[] associated with Registe= r + +**/ +UINTN +EFIAPI +SmramSaveStateGetRegisterIndex ( + IN EFI_SMM_SAVE_STATE_REGISTER Register + ); + +/** + Read a CPU Save State register on the target processor. + + This function abstracts the differences that whether the CPU Save State = register is in the + IA32 CPU Save State Map or X64 CPU Save State Map. + + This function supports reading a CPU Save State register in SMBase reloc= ation handler. + + @param[in] CpuIndex Specifies the zero-based index of the CPU sav= e state. + @param[in] RegisterIndex Index into mSmmSmramCpuWidthOffset[] look up = table. + @param[in] Width The number of bytes to read from the CPU save= state. + @param[out] Buffer Upon return, this holds the CPU register valu= e read from the save state. + + @retval EFI_SUCCESS The register was read from Save State. + @retval EFI_NOT_FOUND The register is not defined for the Save S= tate of Processor. + @retval EFI_INVALID_PARAMTER This or Buffer is NULL. + +**/ +EFI_STATUS +EFIAPI +SmramSaveStateReadRegisterByIndex ( + IN UINTN CpuIndex, + IN UINTN RegisterIndex, + IN UINTN Width, + OUT VOID *Buffer + ); + +#endif diff --git a/UefiCpuPkg/Library/SmmSmramSaveStateLib/AmdSmramSaveState.c b/= UefiCpuPkg/Library/SmmSmramSaveStateLib/AmdSmramSaveState.c new file mode 100644 index 000000000000..8fc4466f473e --- /dev/null +++ b/UefiCpuPkg/Library/SmmSmramSaveStateLib/AmdSmramSaveState.c @@ -0,0 +1,318 @@ +/** @file +Provides services to access SMRAM Save State Map + +Copyright (c) 2010 - 2019, Intel Corporation. All rights reserved.
+Copyright (C) 2023 Advanced Micro Devices, Inc. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "SmramSaveState.h" +#include +#include + +#define EFER_ADDRESS 0XC0000080ul +#define SMM_SAVE_STATE_REGISTER_SMMREVID_INDEX 1 + +// Macro used to simplify the lookup table entries of type CPU_SMM_SAVE_ST= ATE_LOOKUP_ENTRY +#define SMM_CPU_OFFSET(Field) OFFSET_OF (AMD_SMRAM_SAVE_STATE_MAP, Field) + +// Table used by SmramSaveStateGetRegisterIndex() to convert an EFI_SMM_SA= VE_STATE_REGISTER +// value to an index into a table of type CPU_SMM_SAVE_STATE_LOOKUP_ENTRY +CONST CPU_SMM_SAVE_STATE_REGISTER_RANGE mSmmSmramCpuRegisterRanges[] =3D = { + SMM_REGISTER_RANGE (EFI_SMM_SAVE_STATE_REGISTER_GDTBASE, EFI_SMM_SAVE_ST= ATE_REGISTER_LDTINFO), + SMM_REGISTER_RANGE (EFI_SMM_SAVE_STATE_REGISTER_ES, EFI_SMM_SAVE_ST= ATE_REGISTER_RIP), + SMM_REGISTER_RANGE (EFI_SMM_SAVE_STATE_REGISTER_RFLAGS, EFI_SMM_SAVE_ST= ATE_REGISTER_CR4), + { (EFI_SMM_SAVE_STATE_REGISTER)0, (EFI_SMM_SAVE_S= TATE_REGISTER)0, 0} +}; + +// Lookup table used to retrieve the widths and offsets associated with ea= ch +// supported EFI_SMM_SAVE_STATE_REGISTER value +CONST CPU_SMM_SAVE_STATE_LOOKUP_ENTRY mSmmSmramCpuWidthOffset[] =3D { + { 0, 0, 0, 0, = FALSE }, // Reserved + + // + // Internally defined CPU Save State Registers. Not defined in PI SMM CP= U Protocol. + // + { 4, 4, SMM_CPU_OFFSET (x86.SMMRevId), SMM_CPU_OFFSET (x64.SMMRevId), = 0, FALSE}, // SMM_SAVE_STATE_R= EGISTER_SMMREVID_INDEX =3D 1 + + // + // CPU Save State registers defined in PI SMM CPU Protocol. + // + { 4, 8, SMM_CPU_OFFSET (x86.GDTBase), SMM_CPU_OFFSET (x64._GDTRBaseLoDw= ord), SMM_CPU_OFFSET (x64._GDTRBaseHiDword), FALSE}, // EFI_SMM_SAVE_ST= ATE_REGISTER_GDTBASE =3D 4 + { 0, 8, 0, SMM_CPU_OFFSET (x64._IDTRBaseLoDw= ord), SMM_CPU_OFFSET (x64._IDTRBaseLoDword), FALSE}, // EFI_SMM_SAVE_ST= ATE_REGISTER_IDTBASE =3D 5 + { 0, 8, 0, SMM_CPU_OFFSET (x64._LDTRBaseLoDw= ord), SMM_CPU_OFFSET (x64._LDTRBaseLoDword), FALSE}, // EFI_SMM_SAVE_ST= ATE_REGISTER_LDTBASE =3D 6 + { 0, 2, 0, SMM_CPU_OFFSET (x64._GDTRLimit), = 0, FALSE}, // EFI_SMM_SAVE_ST= ATE_REGISTER_GDTLIMIT =3D 7 + { 0, 2, 0, SMM_CPU_OFFSET (x64._IDTRLimit), = 0, FALSE}, // EFI_SMM_SAVE_ST= ATE_REGISTER_IDTLIMIT =3D 8 + { 0, 4, 0, SMM_CPU_OFFSET (x64._LDTRLimit), = 0, FALSE}, // EFI_SMM_SAVE_ST= ATE_REGISTER_LDTLIMIT =3D 9 + { 0, 0, 0, 0, = 0, FALSE}, // EFI_SMM_SAVE_ST= ATE_REGISTER_LDTINFO =3D 10 + { 4, 2, SMM_CPU_OFFSET (x86._ES), SMM_CPU_OFFSET (x64._ES), = 0, FALSE}, // EFI_SMM_SAVE_ST= ATE_REGISTER_ES =3D 20 + { 4, 2, SMM_CPU_OFFSET (x86._CS), SMM_CPU_OFFSET (x64._CS), = 0, FALSE}, // EFI_SMM_SAVE_ST= ATE_REGISTER_CS =3D 21 + { 4, 2, SMM_CPU_OFFSET (x86._SS), SMM_CPU_OFFSET (x64._SS), = 0, FALSE}, // EFI_SMM_SAVE_ST= ATE_REGISTER_SS =3D 22 + { 4, 2, SMM_CPU_OFFSET (x86._DS), SMM_CPU_OFFSET (x64._DS), = 0, FALSE}, // EFI_SMM_SAVE_ST= ATE_REGISTER_DS =3D 23 + { 4, 2, SMM_CPU_OFFSET (x86._FS), SMM_CPU_OFFSET (x64._FS), = 0, FALSE}, // EFI_SMM_SAVE_ST= ATE_REGISTER_FS =3D 24 + { 4, 2, SMM_CPU_OFFSET (x86._GS), SMM_CPU_OFFSET (x64._GS), = 0, FALSE}, // EFI_SMM_SAVE_ST= ATE_REGISTER_GS =3D 25 + { 0, 2, 0, SMM_CPU_OFFSET (x64._LDTR), = 0, FALSE}, // EFI_SMM_SAVE_ST= ATE_REGISTER_LDTR_SEL =3D 26 + { 0, 2, 0, SMM_CPU_OFFSET (x64._TR), = 0, FALSE}, // EFI_SMM_SAVE_ST= ATE_REGISTER_TR_SEL =3D 27 + { 4, 8, SMM_CPU_OFFSET (x86._DR7), SMM_CPU_OFFSET (x64._DR7), = SMM_CPU_OFFSET (x64._DR7) + 4, FALSE}, // EFI_SMM_SAVE_ST= ATE_REGISTER_DR7 =3D 28 + { 4, 8, SMM_CPU_OFFSET (x86._DR6), SMM_CPU_OFFSET (x64._DR6), = SMM_CPU_OFFSET (x64._DR6) + 4, FALSE}, // EFI_SMM_SAVE_ST= ATE_REGISTER_DR6 =3D 29 + { 0, 8, 0, SMM_CPU_OFFSET (x64._R8), = SMM_CPU_OFFSET (x64._R8) + 4, TRUE}, // EFI_SMM_SAVE_ST= ATE_REGISTER_R8 =3D 30 + { 0, 8, 0, SMM_CPU_OFFSET (x64._R9), = SMM_CPU_OFFSET (x64._R9) + 4, TRUE}, // EFI_SMM_SAVE_ST= ATE_REGISTER_R9 =3D 31 + { 0, 8, 0, SMM_CPU_OFFSET (x64._R10), = SMM_CPU_OFFSET (x64._R10) + 4, TRUE}, // EFI_SMM_SAVE_ST= ATE_REGISTER_R10 =3D 32 + { 0, 8, 0, SMM_CPU_OFFSET (x64._R11), = SMM_CPU_OFFSET (x64._R11) + 4, TRUE}, // EFI_SMM_SAVE_ST= ATE_REGISTER_R11 =3D 33 + { 0, 8, 0, SMM_CPU_OFFSET (x64._R12), = SMM_CPU_OFFSET (x64._R12) + 4, TRUE}, // EFI_SMM_SAVE_ST= ATE_REGISTER_R12 =3D 34 + { 0, 8, 0, SMM_CPU_OFFSET (x64._R13), = SMM_CPU_OFFSET (x64._R13) + 4, TRUE}, // EFI_SMM_SAVE_ST= ATE_REGISTER_R13 =3D 35 + { 0, 8, 0, SMM_CPU_OFFSET (x64._R14), = SMM_CPU_OFFSET (x64._R14) + 4, TRUE}, // EFI_SMM_SAVE_ST= ATE_REGISTER_R14 =3D 36 + { 0, 8, 0, SMM_CPU_OFFSET (x64._R15), = SMM_CPU_OFFSET (x64._R15) + 4, TRUE}, // EFI_SMM_SAVE_ST= ATE_REGISTER_R15 =3D 37 + { 4, 8, SMM_CPU_OFFSET (x86._EAX), SMM_CPU_OFFSET (x64._RAX), = SMM_CPU_OFFSET (x64._RAX) + 4, TRUE}, // EFI_SMM_SAVE_ST= ATE_REGISTER_RAX =3D 38 + { 4, 8, SMM_CPU_OFFSET (x86._EBX), SMM_CPU_OFFSET (x64._RBX), = SMM_CPU_OFFSET (x64._RBX) + 4, TRUE}, // EFI_SMM_SAVE_ST= ATE_REGISTER_RBX =3D 39 + { 4, 8, SMM_CPU_OFFSET (x86._ECX), SMM_CPU_OFFSET (x64._RCX), = SMM_CPU_OFFSET (x64._RCX) + 4, TRUE}, // EFI_SMM_SAVE_ST= ATE_REGISTER_RBX =3D 39 + { 4, 8, SMM_CPU_OFFSET (x86._EDX), SMM_CPU_OFFSET (x64._RDX), = SMM_CPU_OFFSET (x64._RDX) + 4, TRUE}, // EFI_SMM_SAVE_ST= ATE_REGISTER_RDX =3D 41 + { 4, 8, SMM_CPU_OFFSET (x86._ESP), SMM_CPU_OFFSET (x64._RSP), = SMM_CPU_OFFSET (x64._RSP) + 4, TRUE}, // EFI_SMM_SAVE_ST= ATE_REGISTER_RSP =3D 42 + { 4, 8, SMM_CPU_OFFSET (x86._EBP), SMM_CPU_OFFSET (x64._RBP), = SMM_CPU_OFFSET (x64._RBP) + 4, TRUE}, // EFI_SMM_SAVE_ST= ATE_REGISTER_RBP =3D 43 + { 4, 8, SMM_CPU_OFFSET (x86._ESI), SMM_CPU_OFFSET (x64._RSI), = SMM_CPU_OFFSET (x64._RSI) + 4, TRUE}, // EFI_SMM_SAVE_ST= ATE_REGISTER_RSI =3D 44 + { 4, 8, SMM_CPU_OFFSET (x86._EDI), SMM_CPU_OFFSET (x64._RDI), = SMM_CPU_OFFSET (x64._RDI) + 4, TRUE}, // EFI_SMM_SAVE_ST= ATE_REGISTER_RDI =3D 45 + { 4, 8, SMM_CPU_OFFSET (x86._EIP), SMM_CPU_OFFSET (x64._RIP), = SMM_CPU_OFFSET (x64._RIP) + 4, TRUE}, // EFI_SMM_SAVE_ST= ATE_REGISTER_RIP =3D 46 + + { 4, 8, SMM_CPU_OFFSET (x86._EFLAGS), SMM_CPU_OFFSET (x64._RFLAGS), = SMM_CPU_OFFSET (x64._RFLAGS) + 4, TRUE}, // EFI_SMM_SAVE_ST= ATE_REGISTER_RFLAGS =3D 51 + { 4, 8, SMM_CPU_OFFSET (x86._CR0), SMM_CPU_OFFSET (x64._CR0), = SMM_CPU_OFFSET (x64._CR0) + 4, FALSE}, // EFI_SMM_SAVE_ST= ATE_REGISTER_CR0 =3D 52 + { 4, 8, SMM_CPU_OFFSET (x86._CR3), SMM_CPU_OFFSET (x64._CR3), = SMM_CPU_OFFSET (x64._CR3) + 4, FALSE}, // EFI_SMM_SAVE_ST= ATE_REGISTER_CR3 =3D 53 + { 0, 8, 0, SMM_CPU_OFFSET (x64._CR4), = SMM_CPU_OFFSET (x64._CR4) + 4, FALSE}, // EFI_SMM_SAVE_ST= ATE_REGISTER_CR4 =3D 54 + { 0, 0, 0, 0, = 0 } +}; + +/** + Read an SMM Save State register on the target processor. If this functi= on + returns EFI_UNSUPPORTED, then the caller is responsible for reading the + SMM Save Sate register. + + @param[in] CpuIndex The index of the CPU to read the SMM Save State. = The + value must be between 0 and the NumberOfCpus field= in + the System Management System Table (SMST). + @param[in] Register The SMM Save State register to read. + @param[in] Width The number of bytes to read from the CPU save stat= e. + @param[out] Buffer Upon return, this holds the CPU register value rea= d + from the save state. + + @retval EFI_SUCCESS The register was read from Save State. + @retval EFI_INVALID_PARAMTER Buffer is NULL. + @retval EFI_UNSUPPORTED This function does not support reading Reg= ister. + @retval EFI_NOT_FOUND If desired Register not found. +**/ +EFI_STATUS +EFIAPI +SmramSaveStateReadRegister ( + IN UINTN CpuIndex, + IN EFI_SMM_SAVE_STATE_REGISTER Register, + IN UINTN Width, + OUT VOID *Buffer + ) +{ + UINT32 SmmRevId; + EFI_SMM_SAVE_STATE_IO_INFO *IoInfo; + AMD_SMRAM_SAVE_STATE_MAP *CpuSaveState; + UINT8 DataWidth; + + // Read CPU State + CpuSaveState =3D (AMD_SMRAM_SAVE_STATE_MAP *)gSmst->CpuSaveState[CpuInde= x]; + + // Check for special EFI_SMM_SAVE_STATE_REGISTER_LMA + if (Register =3D=3D EFI_SMM_SAVE_STATE_REGISTER_LMA) { + // Only byte access is supported for this register + if (Width !=3D 1) { + return EFI_INVALID_PARAMETER; + } + + *(UINT8 *)Buffer =3D SmramSaveStateGetRegisterLma (); + + return EFI_SUCCESS; + } + + // Check for special EFI_SMM_SAVE_STATE_REGISTER_IO + + if (Register =3D=3D EFI_SMM_SAVE_STATE_REGISTER_IO) { + // + // Get SMM Revision ID + // + SmramSaveStateReadRegisterByIndex (CpuIndex, SMM_SAVE_STATE_REGISTER_S= MMREVID_INDEX, sizeof (SmmRevId), &SmmRevId); + + // + // See if the CPU supports the IOMisc register in the save state + // + if (SmmRevId < AMD_SMM_MIN_REV_ID_X64) { + return EFI_NOT_FOUND; + } + + // Check if IO Restart Dword [IO Trap] is valid or not using bit 1. + if (!(CpuSaveState->x64.IO_DWord & 0x02u)) { + return EFI_NOT_FOUND; + } + + // Zero the IoInfo structure that will be returned in Buffer + IoInfo =3D (EFI_SMM_SAVE_STATE_IO_INFO *)Buffer; + ZeroMem (IoInfo, sizeof (EFI_SMM_SAVE_STATE_IO_INFO)); + + IoInfo->IoPort =3D (UINT16)(CpuSaveState->x64.IO_DWord >> 16u); + + if (CpuSaveState->x64.IO_DWord & 0x10u) { + IoInfo->IoWidth =3D EFI_SMM_SAVE_STATE_IO_WIDTH_UINT8; + DataWidth =3D 0x01u; + } else if (CpuSaveState->x64.IO_DWord & 0x20u) { + IoInfo->IoWidth =3D EFI_SMM_SAVE_STATE_IO_WIDTH_UINT16; + DataWidth =3D 0x02u; + } else { + IoInfo->IoWidth =3D EFI_SMM_SAVE_STATE_IO_WIDTH_UINT32; + DataWidth =3D 0x04u; + } + + if (CpuSaveState->x64.IO_DWord & 0x01u) { + IoInfo->IoType =3D EFI_SMM_SAVE_STATE_IO_TYPE_INPUT; + } else { + IoInfo->IoType =3D EFI_SMM_SAVE_STATE_IO_TYPE_OUTPUT; + } + + if ((IoInfo->IoType =3D=3D EFI_SMM_SAVE_STATE_IO_TYPE_INPUT) || (IoInf= o->IoType =3D=3D EFI_SMM_SAVE_STATE_IO_TYPE_OUTPUT)) { + SmramSaveStateReadRegister (CpuIndex, EFI_SMM_SAVE_STATE_REGISTER_RA= X, DataWidth, &IoInfo->IoData); + } + + return EFI_SUCCESS; + } + + // Convert Register to a register lookup table index + return SmramSaveStateReadRegisterByIndex (CpuIndex, SmramSaveStateGetReg= isterIndex (Register), Width, Buffer); +} + +/** + Writes an SMM Save State register on the target processor. If this func= tion + returns EFI_UNSUPPORTED, then the caller is responsible for writing the + SMM Save Sate register. + + @param[in] CpuIndex The index of the CPU to write the SMM Save State. = The + value must be between 0 and the NumberOfCpus field = in + the System Management System Table (SMST). + @param[in] Register The SMM Save State register to write. + @param[in] Width The number of bytes to write to the CPU save state. + @param[in] Buffer Upon entry, this holds the new CPU register value. + + @retval EFI_SUCCESS The register was written to Save State. + @retval EFI_INVALID_PARAMTER Buffer is NULL. + @retval EFI_UNSUPPORTED This function does not support writing Reg= ister. + @retval EFI_NOT_FOUND If desired Register not found. +**/ +EFI_STATUS +EFIAPI +SmramSaveStateWriteRegister ( + IN UINTN CpuIndex, + IN EFI_SMM_SAVE_STATE_REGISTER Register, + IN UINTN Width, + IN CONST VOID *Buffer + ) +{ + UINTN RegisterIndex; + AMD_SMRAM_SAVE_STATE_MAP *CpuSaveState; + + // + // Writes to EFI_SMM_SAVE_STATE_REGISTER_LMA are ignored + // + if (Register =3D=3D EFI_SMM_SAVE_STATE_REGISTER_LMA) { + return EFI_SUCCESS; + } + + // + // Writes to EFI_SMM_SAVE_STATE_REGISTER_IO are not supported + // + if (Register =3D=3D EFI_SMM_SAVE_STATE_REGISTER_IO) { + return EFI_NOT_FOUND; + } + + // + // Convert Register to a register lookup table index + // + RegisterIndex =3D SmramSaveStateGetRegisterIndex (Register); + if (RegisterIndex =3D=3D 0) { + return EFI_NOT_FOUND; + } + + CpuSaveState =3D gSmst->CpuSaveState[CpuIndex]; + + // + // Do not write non-writable SaveState, because it will cause exception. + // + if (!mSmmSmramCpuWidthOffset[RegisterIndex].Writeable) { + return EFI_UNSUPPORTED; + } + + // + // Check CPU mode + // + if (SmramSaveStateGetRegisterLma () =3D=3D EFI_SMM_SAVE_STATE_REGISTER_L= MA_32BIT) { + // + // If 32-bit mode width is zero, then the specified register can not b= e accessed + // + if (mSmmSmramCpuWidthOffset[RegisterIndex].Width32 =3D=3D 0) { + return EFI_NOT_FOUND; + } + + // + // If Width is bigger than the 32-bit mode width, then the specified r= egister can not be accessed + // + if (Width > mSmmSmramCpuWidthOffset[RegisterIndex].Width32) { + return EFI_INVALID_PARAMETER; + } + + // + // Write SMM State register + // + ASSERT (CpuSaveState !=3D NULL); + CopyMem ((UINT8 *)CpuSaveState + mSmmSmramCpuWidthOffset[RegisterIndex= ].Offset32, Buffer, Width); + } else { + // + // If 64-bit mode width is zero, then the specified register can not b= e accessed + // + if (mSmmSmramCpuWidthOffset[RegisterIndex].Width64 =3D=3D 0) { + return EFI_NOT_FOUND; + } + + // + // If Width is bigger than the 64-bit mode width, then the specified r= egister can not be accessed + // + if (Width > mSmmSmramCpuWidthOffset[RegisterIndex].Width64) { + return EFI_INVALID_PARAMETER; + } + + // + // Write lower 32-bits of SMM State register + // + CopyMem ((UINT8 *)CpuSaveState + mSmmSmramCpuWidthOffset[RegisterIndex= ].Offset64Lo, Buffer, MIN (4, Width)); + if (Width >=3D 4) { + // + // Write upper 32-bits of SMM State register + // + CopyMem ((UINT8 *)CpuSaveState + mSmmSmramCpuWidthOffset[RegisterInd= ex].Offset64Hi, (UINT8 *)Buffer + 4, Width - 4); + } + } + + return EFI_SUCCESS; +} + +/** + Returns LMA value of the Processor. + + @param[in] VOID + + @retval UINT8 returns LMA bit value. +**/ +UINT8 +SmramSaveStateGetRegisterLma ( + VOID + ) +{ + UINT32 LMAValue; + + LMAValue =3D (UINT32)AsmReadMsr64 (EFER_ADDRESS) & LMA; + if (LMAValue) { + return EFI_SMM_SAVE_STATE_REGISTER_LMA_64BIT; + } + + return EFI_SMM_SAVE_STATE_REGISTER_LMA_32BIT; +} diff --git a/UefiCpuPkg/Library/SmmSmramSaveStateLib/SmramSaveStateCommon.c= b/UefiCpuPkg/Library/SmmSmramSaveStateLib/SmramSaveStateCommon.c new file mode 100644 index 000000000000..98e89f9eec3f --- /dev/null +++ b/UefiCpuPkg/Library/SmmSmramSaveStateLib/SmramSaveStateCommon.c @@ -0,0 +1,124 @@ +/** @file + Provides common supporting function to access SMRAM Save State Map + + Copyright (c) 2010 - 2019, Intel Corporation. All rights reserved.
+ Copyright (C) 2023 Advanced Micro Devices, Inc. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "SmramSaveState.h" + +extern CONST CPU_SMM_SAVE_STATE_REGISTER_RANGE mSmmSmramCpuRegisterRanges= []; +extern CONST CPU_SMM_SAVE_STATE_LOOKUP_ENTRY mSmmSmramCpuWidthOffset[]; + +/** + Read information from the CPU save state. + + @param Register Specifies the CPU register to read form the save state= . + + @retval 0 Register is not valid + @retval >0 Index into mSmmSmramCpuWidthOffset[] associated with Registe= r + +**/ +UINTN +EFIAPI +SmramSaveStateGetRegisterIndex ( + IN EFI_SMM_SAVE_STATE_REGISTER Register + ) +{ + UINTN Index; + UINTN Offset; + + for (Index =3D 0, Offset =3D SMM_SAVE_STATE_REGISTER_MAX_INDEX; mSmmSmra= mCpuRegisterRanges[Index].Length !=3D 0; Index++) { + if ((Register >=3D mSmmSmramCpuRegisterRanges[Index].Start) && (Regist= er <=3D mSmmSmramCpuRegisterRanges[Index].End)) { + return Register - mSmmSmramCpuRegisterRanges[Index].Start + Offset; + } + + Offset +=3D mSmmSmramCpuRegisterRanges[Index].Length; + } + + return 0; +} + +/** + Read a CPU Save State register on the target processor. + + This function abstracts the differences that whether the CPU Save State = register is in the + IA32 CPU Save State Map or X64 CPU Save State Map. + + This function supports reading a CPU Save State register in SMBase reloc= ation handler. + + @param[in] CpuIndex Specifies the zero-based index of the CPU sav= e state. + @param[in] RegisterIndex Index into mSmmSmramCpuWidthOffset[] look up = table. + @param[in] Width The number of bytes to read from the CPU save= state. + @param[out] Buffer Upon return, this holds the CPU register valu= e read from the save state. + + @retval EFI_SUCCESS The register was read from Save State. + @retval EFI_NOT_FOUND The register is not defined for the Save S= tate of Processor. + @retval EFI_INVALID_PARAMTER This or Buffer is NULL. + +**/ +EFI_STATUS +EFIAPI +SmramSaveStateReadRegisterByIndex ( + IN UINTN CpuIndex, + IN UINTN RegisterIndex, + IN UINTN Width, + OUT VOID *Buffer + ) +{ + if (RegisterIndex =3D=3D 0) { + return EFI_NOT_FOUND; + } + + if (SmramSaveStateGetRegisterLma () =3D=3D EFI_SMM_SAVE_STATE_REGISTER_L= MA_32BIT) { + // + // If 32-bit mode width is zero, then the specified register can not b= e accessed + // + if (mSmmSmramCpuWidthOffset[RegisterIndex].Width32 =3D=3D 0) { + return EFI_NOT_FOUND; + } + + // + // If Width is bigger than the 32-bit mode width, then the specified r= egister can not be accessed + // + if (Width > mSmmSmramCpuWidthOffset[RegisterIndex].Width32) { + return EFI_INVALID_PARAMETER; + } + + // + // Write return buffer + // + ASSERT (gSmst->CpuSaveState[CpuIndex] !=3D NULL); + CopyMem (Buffer, (UINT8 *)gSmst->CpuSaveState[CpuIndex] + mSmmSmramCpu= WidthOffset[RegisterIndex].Offset32, Width); + } else { + // + // If 64-bit mode width is zero, then the specified register can not b= e accessed + // + if (mSmmSmramCpuWidthOffset[RegisterIndex].Width64 =3D=3D 0) { + return EFI_NOT_FOUND; + } + + // + // If Width is bigger than the 64-bit mode width, then the specified r= egister can not be accessed + // + if (Width > mSmmSmramCpuWidthOffset[RegisterIndex].Width64) { + return EFI_INVALID_PARAMETER; + } + + // + // Write lower 32-bits of return buffer + // + CopyMem (Buffer, (UINT8 *)gSmst->CpuSaveState[CpuIndex] + mSmmSmramCpu= WidthOffset[RegisterIndex].Offset64Lo, MIN (4, Width)); + if (Width >=3D 4) { + // + // Write upper 32-bits of return buffer + // + CopyMem ((UINT8 *)Buffer + 4, (UINT8 *)gSmst->CpuSaveState[CpuIndex]= + mSmmSmramCpuWidthOffset[RegisterIndex].Offset64Hi, Width - 4); + } + } + + return EFI_SUCCESS; +} --=20 2.25.1