From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from NAM12-MW2-obe.outbound.protection.outlook.com (NAM12-MW2-obe.outbound.protection.outlook.com [40.107.244.76]) by mx.groups.io with SMTP id smtpd.web10.17367.1673417830787442733 for ; Tue, 10 Jan 2023 22:17:10 -0800 Authentication-Results: mx.groups.io; dkim=pass header.i=@amd.com header.s=selector1 header.b=yNdktlMM; 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.244.76, mailfrom: abdullateef.attar@amd.com) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=Ga5+Wmk2SXSIDUmLVRAj78JC970RefGQJhwZq/W59XZPe6W4Ejwg5mKPtZ8XSuixeD8TbeuqkwLEFLUHjDlPwfU0q1Kml0kYgc7W8/Hd0/yYz69uDJxcKdSsqv4gKqfsLEtj0FJPVxx1h6TbB023r64kERqS7M4/BrJP2iPMA1SSSMF8M1LZOkDMec4ZUFtMvHCj843ff/Wb+puRYPI+bWXgq+wwYC1i9onAm2kN1kMc69lZEErWAHkaamfP/gOqg61pwN3tPx+3DXao2UbAqJkKpOik9jUHUCwcEmIc8jNNxjYOFmnnvHFhNBJ3KzQu2B2OWhLHkBBmOd/wwJFziw== 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=30nORK8wOYKms/gcW6UX9r08XlaeNgHHex077QD6HaM=; b=cmiOz5DYWXwz13glwTUk9oo6VVNl69F5tXmHf+I9XMbKwUDf6bNwRnCxVCyXecPvElZFDOzg9e4vDaOTR8iTklI8VfPmyf6GuH0vhu03QYRGfTyA3c+vtrar9QGX85Qnw9KSuTZ+FK8/XBkrha3lWvLwIUGGZnkt646wYulxJdNU9KAZ7v5Zl8Jbv8uWk6aUsTXUgxC6Nh/DMOiBPZt/Vn8bH/uEk+RFMBktiPvg8tyn/CMFVbOXmYrsGDmZIf+pTOXTLlAIS6jkOB1Q1ojNEbP0bYi1haNv13iuZqYmnPYKsh8jvatsGG8KVD1M3fAtOW7fBgRkClaVRNjHeykwVA== 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=30nORK8wOYKms/gcW6UX9r08XlaeNgHHex077QD6HaM=; b=yNdktlMM3DqLZEwFchTmGAeMHKGB8uf50yIJNLuDAducBBiFkN0Mu775YqeoiRvcz9Zx3uaIU3K53+W8KySEnquLQ7Dzxa+IRZktZRRuGxpXLUu5687Z1leGQUoAIXT69aZhkknmSKjrXkzfkxDc/iqYloSFGkWYud6NRrCyAfg= Received: from DS7PR03CA0309.namprd03.prod.outlook.com (2603:10b6:8:2b::7) by CO6PR12MB5428.namprd12.prod.outlook.com (2603:10b6:5:35c::19) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6002.13; Wed, 11 Jan 2023 06:17:07 +0000 Received: from DS1PEPF0000E64B.namprd02.prod.outlook.com (2603:10b6:8:2b:cafe::8a) by DS7PR03CA0309.outlook.office365.com (2603:10b6:8:2b::7) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5986.18 via Frontend Transport; Wed, 11 Jan 2023 06:17:07 +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=SATLEXMB03.amd.com; pr=C Received: from SATLEXMB03.amd.com (165.204.84.17) by DS1PEPF0000E64B.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.6002.11 via Frontend Transport; Wed, 11 Jan 2023 06:17:07 +0000 Received: from SATLEXMB07.amd.com (10.181.41.45) by SATLEXMB03.amd.com (10.181.40.144) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.34; Wed, 11 Jan 2023 00:17:06 -0600 Received: from SATLEXMB04.amd.com (10.181.40.145) by SATLEXMB07.amd.com (10.181.41.45) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.34; Tue, 10 Jan 2023 22:17:06 -0800 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; Wed, 11 Jan 2023 00:17:01 -0600 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 v2 4/6] UefiCpuPkg: Implements SmmSmramSaveStateLib library class Date: Wed, 11 Jan 2023 11:45:42 +0530 Message-ID: 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: DS1PEPF0000E64B:EE_|CO6PR12MB5428:EE_ X-MS-Office365-Filtering-Correlation-Id: 2dce77a8-7a58-478e-7387-08daf39b7758 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: wXer88p7ZaC7MsrYdtARozp8vfqte+gAla9gAc2PQdnmWllc8QXj9L5nVxVLlHd7uaDcsE3AZv0Dv8PuzTewuQPuR801eGLT37L7Gccr/8h4pY9JjIfDPEHOs4jE9uta01GZJVHBPysvcjpDT4gnYH7YZ8Y5kAc0/RMZpTUTkJGZbkeWqZiyaOqE/fv8Hs9gYmhq6gIWmOytZfEvOPPi+cCsYYzn3tYaYEA8VO6T3pg6T6+EqCJ3l/hyEtr9o8aNu8eolRz7e+IXJCfho/+IyMaGy7MWQtOgNj31R2BkE0xFtKiojvGRB9jCyPIBiQ3Q6HhRpRwUqzSxF1j/wwgYChYTmB3+1N8hGEPq1KjmnefCTp9/TtOjTt43VCPf5Oc+ui03m4tT4f6ImQqtBf72UdRIkMdpFJlZ7uq8plQRWMWA5WU6eIpNskUY4mQXhJVcPjVC223omhKIzsVOD+IQic6Wx4qJtJdvC/M9X2yatmeq6yTIrvrpzoP9AinXNFNLhuwdXcTk4ejavWglao8dGzPuFXBcZtLLPNDPAVoa7IEw7p5WeuDBywFqzvkwX8xvNEt1aG7m1Pa60KZC+bUS7HlQmicdzXa/XRknmKoNCKLCojPhvx4+l/K/43KWw+9xF9wDlvFTftghCgkE6IU7/+kNSf3A5ZHEkYq0qthQC4rOrnstcQb770/q3JVOyBSFcNXPdarD+Fo2VPZWW3WeZWL9gAitE85SkRMRYkINB1s/ab90jR8ft79wCo6CIYCFQK80VTnk9cRJFEZk2KXKsRpXUJmVnWK7EO3tVbtMNhQ= X-Forefront-Antispam-Report: CIP:165.204.84.17;CTRY:US;LANG:en;SCL:1;SRV:;IPV:CAL;SFV:NSPM;H:SATLEXMB03.amd.com;PTR:InfoDomainNonexistent;CAT:NONE;SFS:(13230022)(4636009)(346002)(396003)(136003)(376002)(39860400002)(451199015)(40470700004)(36840700001)(46966006)(6666004)(36860700001)(2906002)(36756003)(4326008)(6916009)(8676002)(5660300002)(83380400001)(8936002)(30864003)(82740400003)(356005)(81166007)(47076005)(41300700001)(966005)(478600001)(426003)(336012)(26005)(82310400005)(186003)(70206006)(70586007)(40480700001)(7696005)(40460700003)(316002)(2616005)(54906003)(213903007)(36900700001);DIR:OUT;SFP:1101; X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 11 Jan 2023 06:17:07.3331 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 2dce77a8-7a58-478e-7387-08daf39b7758 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=[SATLEXMB03.amd.com] X-MS-Exchange-CrossTenant-AuthSource: DS1PEPF0000E64B.namprd02.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: CO6PR12MB5428 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 --- UefiCpuPkg/UefiCpuPkg.dsc | 3 + .../AmdSmmSmramSaveStateLib.inf | 28 ++ .../SmmSmramSaveStateLib/SmramSaveState.h | 102 ++++++ .../SmmSmramSaveStateLib/Amd/SmramSaveState.c | 318 ++++++++++++++++++ .../SmramSaveStateCommon.c | 124 +++++++ 5 files changed, 575 insertions(+) create mode 100644 UefiCpuPkg/Library/SmmSmramSaveStateLib/AmdSmmSmramSave= StateLib.inf create mode 100644 UefiCpuPkg/Library/SmmSmramSaveStateLib/SmramSaveState.h create mode 100644 UefiCpuPkg/Library/SmmSmramSaveStateLib/Amd/SmramSaveSt= ate.c create mode 100644 UefiCpuPkg/Library/SmmSmramSaveStateLib/SmramSaveStateC= ommon.c diff --git a/UefiCpuPkg/UefiCpuPkg.dsc b/UefiCpuPkg/UefiCpuPkg.dsc index f9a46089d2c7..99f7532ce00b 100644 --- a/UefiCpuPkg/UefiCpuPkg.dsc +++ b/UefiCpuPkg/UefiCpuPkg.dsc @@ -2,6 +2,7 @@ # UefiCpuPkg Package=0D #=0D # Copyright (c) 2007 - 2022, Intel Corporation. All rights reserved.
= =0D +# Copyright (C) 2023 Advanced Micro Devices, Inc. All rights reserved.=0D #=0D # SPDX-License-Identifier: BSD-2-Clause-Patent=0D #=0D @@ -104,6 +105,7 @@ [LibraryClasses.common.DXE_SMM_DRIVER] MemoryAllocationLib|MdePkg/Library/SmmMemoryAllocationLib/SmmMemoryAlloc= ationLib.inf=0D HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf=0D CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/SmmCpuE= xceptionHandlerLib.inf=0D + SmmSmramSaveStateLib|UefiCpuPkg/Library/SmmSmramSaveStateLib/AmdSmmSmram= SaveStateLib.inf=0D =0D [LibraryClasses.common.MM_STANDALONE]=0D MmServicesTableLib|MdePkg/Library/StandaloneMmServicesTableLib/Standalon= eMmServicesTableLib.inf=0D @@ -191,6 +193,7 @@ [Components.IA32, Components.X64] =0D UnitTestResultReportLib|UnitTestFrameworkPkg/Library/UnitTestResultR= eportLib/UnitTestResultReportLibConOut.inf=0D }=0D + UefiCpuPkg/Library/SmmSmramSaveStateLib/AmdSmmSmramSaveStateLib.inf=0D =0D [Components.X64]=0D UefiCpuPkg/Library/CpuExceptionHandlerLib/UnitTest/DxeCpuExceptionHandle= rLibUnitTest.inf=0D diff --git a/UefiCpuPkg/Library/SmmSmramSaveStateLib/AmdSmmSmramSaveStateLi= b.inf b/UefiCpuPkg/Library/SmmSmramSaveStateLib/AmdSmmSmramSaveStateLib.inf new file mode 100644 index 000000000000..463e4c9331be --- /dev/null +++ b/UefiCpuPkg/Library/SmmSmramSaveStateLib/AmdSmmSmramSaveStateLib.inf @@ -0,0 +1,28 @@ +## @file=0D +# SMM Smram save state service lib.=0D +#=0D +# This is SMM Smram save state service lib that provide service to read an= d=0D +# save savestate area registers.=0D +#=0D +# Copyright (C) 2023 Advanced Micro Devices, Inc. All rights reserved.
= =0D +#=0D +# SPDX-License-Identifier: BSD-2-Clause-Patent=0D +#=0D +##=0D +=0D +[Defines]=0D + INF_VERSION =3D 1.29=0D + BASE_NAME =3D AmdSmmSmramSaveStateLib=0D + FILE_GUID =3D FB7D0A60-E8D4-4EFA-90AA-B357BC569879= =0D + MODULE_TYPE =3D DXE_SMM_DRIVER=0D + VERSION_STRING =3D 1.0=0D + LIBRARY_CLASS =3D SmmSmramSaveStateLib=0D +=0D +[Sources]=0D + SmramSaveState.h=0D + SmramSaveStateCommon.c=0D + Amd/SmramSaveState.c=0D +=0D +[Packages]=0D + MdePkg/MdePkg.dec=0D + UefiCpuPkg/UefiCpuPkg.dec=0D diff --git a/UefiCpuPkg/Library/SmmSmramSaveStateLib/SmramSaveState.h b/Uef= iCpuPkg/Library/SmmSmramSaveStateLib/SmramSaveState.h new file mode 100644 index 000000000000..c55ae004e016 --- /dev/null +++ b/UefiCpuPkg/Library/SmmSmramSaveStateLib/SmramSaveState.h @@ -0,0 +1,102 @@ +/** @file=0D + SMRAM Save State Map header file.=0D +=0D + Copyright (c) 2010 - 2019, Intel Corporation. All rights reserved.
=0D + Copyright (C) 2023 Advanced Micro Devices, Inc. All rights reserved.
= =0D + SPDX-License-Identifier: BSD-2-Clause-Patent=0D +=0D +**/=0D +=0D +#ifndef SMRAM_SAVESTATE_H_=0D +#define SMRAM_SAVESTATE_H_=0D +=0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +=0D +// EFER register LMA bit=0D +#define LMA BIT10=0D +=0D +// Macro used to simplify the lookup table entries of type CPU_SMM_SAVE_ST= ATE_REGISTER_RANGE=0D +#define SMM_REGISTER_RANGE(Start, End) { Start, End, End - Start + 1 }=0D +=0D +#define SMM_SAVE_STATE_REGISTER_MAX_INDEX 2=0D +=0D +// Structure used to describe a range of registers=0D +typedef struct {=0D + EFI_SMM_SAVE_STATE_REGISTER Start;=0D + EFI_SMM_SAVE_STATE_REGISTER End;=0D + UINTN Length;=0D +} CPU_SMM_SAVE_STATE_REGISTER_RANGE;=0D +=0D +// Structure used to build a lookup table to retrieve the widths and offse= ts=0D +// associated with each supported EFI_SMM_SAVE_STATE_REGISTER value=0D +=0D +typedef struct {=0D + UINT8 Width32;=0D + UINT8 Width64;=0D + UINT16 Offset32;=0D + UINT16 Offset64Lo;=0D + UINT16 Offset64Hi;=0D + BOOLEAN Writeable;=0D +} CPU_SMM_SAVE_STATE_LOOKUP_ENTRY;=0D +=0D +/**=0D + Returns LMA value of the Processor.=0D +=0D + @param[in] VOID=0D +=0D + @retval UINT8 returns LMA bit value.=0D +**/=0D +UINT8=0D +EFIAPI=0D +SmramSaveStateGetRegisterLma (=0D + VOID=0D + );=0D +=0D +/**=0D + Read information from the CPU save state.=0D +=0D + @param Register Specifies the CPU register to read form the save state= .=0D +=0D + @retval 0 Register is not valid=0D + @retval >0 Index into mSmmSmramCpuWidthOffset[] associated with Registe= r=0D +=0D +**/=0D +UINTN=0D +EFIAPI=0D +SmramSaveStateGetRegisterIndex (=0D + IN EFI_SMM_SAVE_STATE_REGISTER Register=0D + );=0D +=0D +/**=0D + Read a CPU Save State register on the target processor.=0D +=0D + This function abstracts the differences that whether the CPU Save State = register is in the=0D + IA32 CPU Save State Map or X64 CPU Save State Map.=0D +=0D + This function supports reading a CPU Save State register in SMBase reloc= ation handler.=0D +=0D + @param[in] CpuIndex Specifies the zero-based index of the CPU sav= e state.=0D + @param[in] RegisterIndex Index into mSmmSmramCpuWidthOffset[] look up = table.=0D + @param[in] Width The number of bytes to read from the CPU save= state.=0D + @param[out] Buffer Upon return, this holds the CPU register valu= e read from the save state.=0D +=0D + @retval EFI_SUCCESS The register was read from Save State.=0D + @retval EFI_NOT_FOUND The register is not defined for the Save S= tate of Processor.=0D + @retval EFI_INVALID_PARAMTER This or Buffer is NULL.=0D +=0D +**/=0D +EFI_STATUS=0D +EFIAPI=0D +SmramSaveStateReadRegisterByIndex (=0D + IN UINTN CpuIndex,=0D + IN UINTN RegisterIndex,=0D + IN UINTN Width,=0D + OUT VOID *Buffer=0D + );=0D +=0D +#endif=0D diff --git a/UefiCpuPkg/Library/SmmSmramSaveStateLib/Amd/SmramSaveState.c b= /UefiCpuPkg/Library/SmmSmramSaveStateLib/Amd/SmramSaveState.c new file mode 100644 index 000000000000..af2eeedc71f5 --- /dev/null +++ b/UefiCpuPkg/Library/SmmSmramSaveStateLib/Amd/SmramSaveState.c @@ -0,0 +1,318 @@ +/** @file=0D +Provides services to access SMRAM Save State Map=0D +=0D +Copyright (c) 2010 - 2019, Intel Corporation. All rights reserved.
=0D +Copyright (C) 2023 Advanced Micro Devices, Inc. All rights reserved.
=0D +SPDX-License-Identifier: BSD-2-Clause-Patent=0D +=0D +**/=0D +=0D +#include "SmramSaveState.h"=0D +#include =0D +#include =0D +=0D +#define EFER_ADDRESS 0XC0000080ul=0D +#define SMM_SAVE_STATE_REGISTER_SMMREVID_INDEX 1=0D +=0D +// Macro used to simplify the lookup table entries of type CPU_SMM_SAVE_ST= ATE_LOOKUP_ENTRY=0D +#define SMM_CPU_OFFSET(Field) OFFSET_OF (AMD_SMRAM_SAVE_STATE_MAP, Field)= =0D +=0D +// Table used by SmramSaveStateGetRegisterIndex() to convert an EFI_SMM_SA= VE_STATE_REGISTER=0D +// value to an index into a table of type CPU_SMM_SAVE_STATE_LOOKUP_ENTRY= =0D +CONST CPU_SMM_SAVE_STATE_REGISTER_RANGE mSmmSmramCpuRegisterRanges[] =3D = {=0D + SMM_REGISTER_RANGE (EFI_SMM_SAVE_STATE_REGISTER_GDTBASE, EFI_SMM_SAVE_ST= ATE_REGISTER_LDTINFO),=0D + SMM_REGISTER_RANGE (EFI_SMM_SAVE_STATE_REGISTER_ES, EFI_SMM_SAVE_ST= ATE_REGISTER_RIP),=0D + SMM_REGISTER_RANGE (EFI_SMM_SAVE_STATE_REGISTER_RFLAGS, EFI_SMM_SAVE_ST= ATE_REGISTER_CR4),=0D + { (EFI_SMM_SAVE_STATE_REGISTER)0, (EFI_SMM_SAVE_S= TATE_REGISTER)0, 0}=0D +};=0D +=0D +// Lookup table used to retrieve the widths and offsets associated with ea= ch=0D +// supported EFI_SMM_SAVE_STATE_REGISTER value=0D +CONST CPU_SMM_SAVE_STATE_LOOKUP_ENTRY mSmmSmramCpuWidthOffset[] =3D {=0D + { 0, 0, 0, 0, = FALSE }, // Reserved=0D +=0D + //=0D + // Internally defined CPU Save State Registers. Not defined in PI SMM CP= U Protocol.=0D + //=0D + { 4, 4, SMM_CPU_OFFSET (x86.SMMRevId), SMM_CPU_OFFSET (x64.SMMRevId), = 0, FALSE}, // SMM_SAVE_STATE_R= EGISTER_SMMREVID_INDEX =3D 1=0D +=0D + //=0D + // CPU Save State registers defined in PI SMM CPU Protocol.=0D + //=0D + { 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=0D + { 0, 8, 0, SMM_CPU_OFFSET (x64._IDTRBaseLoDw= ord), SMM_CPU_OFFSET (x64._IDTRBaseLoDword), FALSE}, // EFI_SMM_SAVE_ST= ATE_REGISTER_IDTBASE =3D 5=0D + { 0, 8, 0, SMM_CPU_OFFSET (x64._LDTRBaseLoDw= ord), SMM_CPU_OFFSET (x64._LDTRBaseLoDword), FALSE}, // EFI_SMM_SAVE_ST= ATE_REGISTER_LDTBASE =3D 6=0D + { 0, 2, 0, SMM_CPU_OFFSET (x64._GDTRLimit), = 0, FALSE}, // EFI_SMM_SAVE_ST= ATE_REGISTER_GDTLIMIT =3D 7=0D + { 0, 2, 0, SMM_CPU_OFFSET (x64._IDTRLimit), = 0, FALSE}, // EFI_SMM_SAVE_ST= ATE_REGISTER_IDTLIMIT =3D 8=0D + { 0, 4, 0, SMM_CPU_OFFSET (x64._LDTRLimit), = 0, FALSE}, // EFI_SMM_SAVE_ST= ATE_REGISTER_LDTLIMIT =3D 9=0D + { 0, 0, 0, 0, = 0, FALSE}, // EFI_SMM_SAVE_ST= ATE_REGISTER_LDTINFO =3D 10=0D + { 4, 2, SMM_CPU_OFFSET (x86._ES), SMM_CPU_OFFSET (x64._ES), = 0, FALSE}, // EFI_SMM_SAVE_ST= ATE_REGISTER_ES =3D 20=0D + { 4, 2, SMM_CPU_OFFSET (x86._CS), SMM_CPU_OFFSET (x64._CS), = 0, FALSE}, // EFI_SMM_SAVE_ST= ATE_REGISTER_CS =3D 21=0D + { 4, 2, SMM_CPU_OFFSET (x86._SS), SMM_CPU_OFFSET (x64._SS), = 0, FALSE}, // EFI_SMM_SAVE_ST= ATE_REGISTER_SS =3D 22=0D + { 4, 2, SMM_CPU_OFFSET (x86._DS), SMM_CPU_OFFSET (x64._DS), = 0, FALSE}, // EFI_SMM_SAVE_ST= ATE_REGISTER_DS =3D 23=0D + { 4, 2, SMM_CPU_OFFSET (x86._FS), SMM_CPU_OFFSET (x64._FS), = 0, FALSE}, // EFI_SMM_SAVE_ST= ATE_REGISTER_FS =3D 24=0D + { 4, 2, SMM_CPU_OFFSET (x86._GS), SMM_CPU_OFFSET (x64._GS), = 0, FALSE}, // EFI_SMM_SAVE_ST= ATE_REGISTER_GS =3D 25=0D + { 0, 2, 0, SMM_CPU_OFFSET (x64._LDTR), = 0, FALSE}, // EFI_SMM_SAVE_ST= ATE_REGISTER_LDTR_SEL =3D 26=0D + { 0, 2, 0, SMM_CPU_OFFSET (x64._TR), = 0, FALSE}, // EFI_SMM_SAVE_ST= ATE_REGISTER_TR_SEL =3D 27=0D + { 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=0D + { 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=0D + { 0, 8, 0, SMM_CPU_OFFSET (x64._R8), = SMM_CPU_OFFSET (x64._R8) + 4, TRUE}, // EFI_SMM_SAVE_ST= ATE_REGISTER_R8 =3D 30=0D + { 0, 8, 0, SMM_CPU_OFFSET (x64._R9), = SMM_CPU_OFFSET (x64._R9) + 4, TRUE}, // EFI_SMM_SAVE_ST= ATE_REGISTER_R9 =3D 31=0D + { 0, 8, 0, SMM_CPU_OFFSET (x64._R10), = SMM_CPU_OFFSET (x64._R10) + 4, TRUE}, // EFI_SMM_SAVE_ST= ATE_REGISTER_R10 =3D 32=0D + { 0, 8, 0, SMM_CPU_OFFSET (x64._R11), = SMM_CPU_OFFSET (x64._R11) + 4, TRUE}, // EFI_SMM_SAVE_ST= ATE_REGISTER_R11 =3D 33=0D + { 0, 8, 0, SMM_CPU_OFFSET (x64._R12), = SMM_CPU_OFFSET (x64._R12) + 4, TRUE}, // EFI_SMM_SAVE_ST= ATE_REGISTER_R12 =3D 34=0D + { 0, 8, 0, SMM_CPU_OFFSET (x64._R13), = SMM_CPU_OFFSET (x64._R13) + 4, TRUE}, // EFI_SMM_SAVE_ST= ATE_REGISTER_R13 =3D 35=0D + { 0, 8, 0, SMM_CPU_OFFSET (x64._R14), = SMM_CPU_OFFSET (x64._R14) + 4, TRUE}, // EFI_SMM_SAVE_ST= ATE_REGISTER_R14 =3D 36=0D + { 0, 8, 0, SMM_CPU_OFFSET (x64._R15), = SMM_CPU_OFFSET (x64._R15) + 4, TRUE}, // EFI_SMM_SAVE_ST= ATE_REGISTER_R15 =3D 37=0D + { 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=0D + { 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=0D + { 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=0D + { 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=0D + { 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=0D + { 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=0D + { 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=0D + { 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=0D + { 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=0D +=0D + { 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=0D + { 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=0D + { 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=0D + { 0, 8, 0, SMM_CPU_OFFSET (x64._CR4), = SMM_CPU_OFFSET (x64._CR4) + 4, FALSE}, // EFI_SMM_SAVE_ST= ATE_REGISTER_CR4 =3D 54=0D + { 0, 0, 0, 0, = 0 }=0D +};=0D +=0D +/**=0D + Read an SMM Save State register on the target processor. If this functi= on=0D + returns EFI_UNSUPPORTED, then the caller is responsible for reading the= =0D + SMM Save Sate register.=0D +=0D + @param[in] CpuIndex The index of the CPU to read the SMM Save State. = The=0D + value must be between 0 and the NumberOfCpus field= in=0D + the System Management System Table (SMST).=0D + @param[in] Register The SMM Save State register to read.=0D + @param[in] Width The number of bytes to read from the CPU save stat= e.=0D + @param[out] Buffer Upon return, this holds the CPU register value rea= d=0D + from the save state.=0D +=0D + @retval EFI_SUCCESS The register was read from Save State.=0D + @retval EFI_INVALID_PARAMTER Buffer is NULL.=0D + @retval EFI_UNSUPPORTED This function does not support reading Reg= ister.=0D +=0D +**/=0D +EFI_STATUS=0D +EFIAPI=0D +SmramSaveStateReadRegister (=0D + IN UINTN CpuIndex,=0D + IN EFI_SMM_SAVE_STATE_REGISTER Register,=0D + IN UINTN Width,=0D + OUT VOID *Buffer=0D + )=0D +{=0D + UINT32 SmmRevId;=0D + EFI_SMM_SAVE_STATE_IO_INFO *IoInfo;=0D + AMD_SMRAM_SAVE_STATE_MAP *CpuSaveState;=0D + UINT8 DataWidth;=0D +=0D + // Read CPU State=0D + CpuSaveState =3D (AMD_SMRAM_SAVE_STATE_MAP *)gSmst->CpuSaveState[CpuInde= x];=0D +=0D + // Check for special EFI_SMM_SAVE_STATE_REGISTER_LMA=0D + if (Register =3D=3D EFI_SMM_SAVE_STATE_REGISTER_LMA) {=0D + // Only byte access is supported for this register=0D + if (Width !=3D 1) {=0D + return EFI_INVALID_PARAMETER;=0D + }=0D +=0D + *(UINT8 *)Buffer =3D SmramSaveStateGetRegisterLma ();=0D +=0D + return EFI_SUCCESS;=0D + }=0D +=0D + // Check for special EFI_SMM_SAVE_STATE_REGISTER_IO=0D +=0D + if (Register =3D=3D EFI_SMM_SAVE_STATE_REGISTER_IO) {=0D + //=0D + // Get SMM Revision ID=0D + //=0D + SmramSaveStateReadRegisterByIndex (CpuIndex, SMM_SAVE_STATE_REGISTER_S= MMREVID_INDEX, sizeof (SmmRevId), &SmmRevId);=0D +=0D + //=0D + // See if the CPU supports the IOMisc register in the save state=0D + //=0D + if (SmmRevId < AMD_SMM_MIN_REV_ID_X64) {=0D + return EFI_NOT_FOUND;=0D + }=0D +=0D + // Check if IO Restart Dword [IO Trap] is valid or not using bit 1.=0D + if (!(CpuSaveState->x64.IO_DWord & 0x02u)) {=0D + return EFI_NOT_FOUND;=0D + }=0D +=0D + // Zero the IoInfo structure that will be returned in Buffer=0D + IoInfo =3D (EFI_SMM_SAVE_STATE_IO_INFO *)Buffer;=0D + ZeroMem (IoInfo, sizeof (EFI_SMM_SAVE_STATE_IO_INFO));=0D +=0D + IoInfo->IoPort =3D (UINT16)(CpuSaveState->x64.IO_DWord >> 16u);=0D +=0D + if (CpuSaveState->x64.IO_DWord & 0x10u) {=0D + IoInfo->IoWidth =3D EFI_SMM_SAVE_STATE_IO_WIDTH_UINT8;=0D + DataWidth =3D 0x01u;=0D + } else if (CpuSaveState->x64.IO_DWord & 0x20u) {=0D + IoInfo->IoWidth =3D EFI_SMM_SAVE_STATE_IO_WIDTH_UINT16;=0D + DataWidth =3D 0x02u;=0D + } else {=0D + IoInfo->IoWidth =3D EFI_SMM_SAVE_STATE_IO_WIDTH_UINT32;=0D + DataWidth =3D 0x04u;=0D + }=0D +=0D + if (CpuSaveState->x64.IO_DWord & 0x01u) {=0D + IoInfo->IoType =3D EFI_SMM_SAVE_STATE_IO_TYPE_INPUT;=0D + } else {=0D + IoInfo->IoType =3D EFI_SMM_SAVE_STATE_IO_TYPE_OUTPUT;=0D + }=0D +=0D + if ((IoInfo->IoType =3D=3D EFI_SMM_SAVE_STATE_IO_TYPE_INPUT) || (IoInf= o->IoType =3D=3D EFI_SMM_SAVE_STATE_IO_TYPE_OUTPUT)) {=0D + SmramSaveStateReadRegister (CpuIndex, EFI_SMM_SAVE_STATE_REGISTER_RA= X, DataWidth, &IoInfo->IoData);=0D + }=0D +=0D + return EFI_SUCCESS;=0D + }=0D +=0D + // Convert Register to a register lookup table index=0D + return SmramSaveStateReadRegisterByIndex (CpuIndex, SmramSaveStateGetReg= isterIndex (Register), Width, Buffer);=0D +}=0D +=0D +/**=0D + Writes an SMM Save State register on the target processor. If this func= tion=0D + returns EFI_UNSUPPORTED, then the caller is responsible for writing the= =0D + SMM Save Sate register.=0D +=0D + @param[in] CpuIndex The index of the CPU to write the SMM Save State. = The=0D + value must be between 0 and the NumberOfCpus field = in=0D + the System Management System Table (SMST).=0D + @param[in] Register The SMM Save State register to write.=0D + @param[in] Width The number of bytes to write to the CPU save state.= =0D + @param[in] Buffer Upon entry, this holds the new CPU register value.= =0D +=0D + @retval EFI_SUCCESS The register was written to Save State.=0D + @retval EFI_INVALID_PARAMTER Buffer is NULL.=0D + @retval EFI_UNSUPPORTED This function does not support writing Reg= ister.=0D +**/=0D +EFI_STATUS=0D +EFIAPI=0D +SmramSaveStateWriteRegister (=0D + IN UINTN CpuIndex,=0D + IN EFI_SMM_SAVE_STATE_REGISTER Register,=0D + IN UINTN Width,=0D + IN CONST VOID *Buffer=0D + )=0D +{=0D + UINTN RegisterIndex;=0D + AMD_SMRAM_SAVE_STATE_MAP *CpuSaveState;=0D +=0D + //=0D + // Writes to EFI_SMM_SAVE_STATE_REGISTER_LMA are ignored=0D + //=0D + if (Register =3D=3D EFI_SMM_SAVE_STATE_REGISTER_LMA) {=0D + return EFI_SUCCESS;=0D + }=0D +=0D + //=0D + // Writes to EFI_SMM_SAVE_STATE_REGISTER_IO are not supported=0D + //=0D + if (Register =3D=3D EFI_SMM_SAVE_STATE_REGISTER_IO) {=0D + return EFI_NOT_FOUND;=0D + }=0D +=0D + //=0D + // Convert Register to a register lookup table index=0D + //=0D + RegisterIndex =3D SmramSaveStateGetRegisterIndex (Register);=0D + if (RegisterIndex =3D=3D 0) {=0D + return EFI_NOT_FOUND;=0D + }=0D +=0D + CpuSaveState =3D gSmst->CpuSaveState[CpuIndex];=0D +=0D + //=0D + // Do not write non-writable SaveState, because it will cause exception.= =0D + //=0D + if (!mSmmSmramCpuWidthOffset[RegisterIndex].Writeable) {=0D + return EFI_UNSUPPORTED;=0D + }=0D +=0D + //=0D + // Check CPU mode=0D + //=0D + if (SmramSaveStateGetRegisterLma () =3D=3D EFI_SMM_SAVE_STATE_REGISTER_L= MA_32BIT) {=0D + //=0D + // If 32-bit mode width is zero, then the specified register can not b= e accessed=0D + //=0D + if (mSmmSmramCpuWidthOffset[RegisterIndex].Width32 =3D=3D 0) {=0D + return EFI_NOT_FOUND;=0D + }=0D +=0D + //=0D + // If Width is bigger than the 32-bit mode width, then the specified r= egister can not be accessed=0D + //=0D + if (Width > mSmmSmramCpuWidthOffset[RegisterIndex].Width32) {=0D + return EFI_INVALID_PARAMETER;=0D + }=0D +=0D + //=0D + // Write SMM State register=0D + //=0D + ASSERT (CpuSaveState !=3D NULL);=0D + CopyMem ((UINT8 *)CpuSaveState + mSmmSmramCpuWidthOffset[RegisterIndex= ].Offset32, Buffer, Width);=0D + } else {=0D + //=0D + // If 64-bit mode width is zero, then the specified register can not b= e accessed=0D + //=0D + if (mSmmSmramCpuWidthOffset[RegisterIndex].Width64 =3D=3D 0) {=0D + return EFI_NOT_FOUND;=0D + }=0D +=0D + //=0D + // If Width is bigger than the 64-bit mode width, then the specified r= egister can not be accessed=0D + //=0D + if (Width > mSmmSmramCpuWidthOffset[RegisterIndex].Width64) {=0D + return EFI_INVALID_PARAMETER;=0D + }=0D +=0D + //=0D + // Write lower 32-bits of SMM State register=0D + //=0D + CopyMem ((UINT8 *)CpuSaveState + mSmmSmramCpuWidthOffset[RegisterIndex= ].Offset64Lo, Buffer, MIN (4, Width));=0D + if (Width >=3D 4) {=0D + //=0D + // Write upper 32-bits of SMM State register=0D + //=0D + CopyMem ((UINT8 *)CpuSaveState + mSmmSmramCpuWidthOffset[RegisterInd= ex].Offset64Hi, (UINT8 *)Buffer + 4, Width - 4);=0D + }=0D + }=0D +=0D + return EFI_SUCCESS;=0D +}=0D +=0D +/**=0D + Returns LMA value of the Processor.=0D +=0D + @param[in] VOID=0D +=0D + @retval UINT8 returns LMA bit value.=0D +**/=0D +UINT8=0D +EFIAPI=0D +SmramSaveStateGetRegisterLma (=0D + VOID=0D + )=0D +{=0D + UINT32 LMAValue;=0D +=0D + LMAValue =3D (UINT32)AsmReadMsr64 (EFER_ADDRESS) & LMA;=0D + if (LMAValue) {=0D + return EFI_SMM_SAVE_STATE_REGISTER_LMA_64BIT;=0D + }=0D +=0D + return EFI_SMM_SAVE_STATE_REGISTER_LMA_32BIT;=0D +}=0D 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=0D + Provides common supporting function to access SMRAM Save State Map=0D +=0D + Copyright (c) 2010 - 2019, Intel Corporation. All rights reserved.
=0D + Copyright (C) 2023 Advanced Micro Devices, Inc. All rights reserved.
= =0D +=0D + SPDX-License-Identifier: BSD-2-Clause-Patent=0D +=0D +**/=0D +=0D +#include "SmramSaveState.h"=0D +=0D +extern CONST CPU_SMM_SAVE_STATE_REGISTER_RANGE mSmmSmramCpuRegisterRanges= [];=0D +extern CONST CPU_SMM_SAVE_STATE_LOOKUP_ENTRY mSmmSmramCpuWidthOffset[];= =0D +=0D +/**=0D + Read information from the CPU save state.=0D +=0D + @param Register Specifies the CPU register to read form the save state= .=0D +=0D + @retval 0 Register is not valid=0D + @retval >0 Index into mSmmSmramCpuWidthOffset[] associated with Registe= r=0D +=0D +**/=0D +UINTN=0D +EFIAPI=0D +SmramSaveStateGetRegisterIndex (=0D + IN EFI_SMM_SAVE_STATE_REGISTER Register=0D + )=0D +{=0D + UINTN Index;=0D + UINTN Offset;=0D +=0D + for (Index =3D 0, Offset =3D SMM_SAVE_STATE_REGISTER_MAX_INDEX; mSmmSmra= mCpuRegisterRanges[Index].Length !=3D 0; Index++) {=0D + if ((Register >=3D mSmmSmramCpuRegisterRanges[Index].Start) && (Regist= er <=3D mSmmSmramCpuRegisterRanges[Index].End)) {=0D + return Register - mSmmSmramCpuRegisterRanges[Index].Start + Offset;= =0D + }=0D +=0D + Offset +=3D mSmmSmramCpuRegisterRanges[Index].Length;=0D + }=0D +=0D + return 0;=0D +}=0D +=0D +/**=0D + Read a CPU Save State register on the target processor.=0D +=0D + This function abstracts the differences that whether the CPU Save State = register is in the=0D + IA32 CPU Save State Map or X64 CPU Save State Map.=0D +=0D + This function supports reading a CPU Save State register in SMBase reloc= ation handler.=0D +=0D + @param[in] CpuIndex Specifies the zero-based index of the CPU sav= e state.=0D + @param[in] RegisterIndex Index into mSmmSmramCpuWidthOffset[] look up = table.=0D + @param[in] Width The number of bytes to read from the CPU save= state.=0D + @param[out] Buffer Upon return, this holds the CPU register valu= e read from the save state.=0D +=0D + @retval EFI_SUCCESS The register was read from Save State.=0D + @retval EFI_NOT_FOUND The register is not defined for the Save S= tate of Processor.=0D + @retval EFI_INVALID_PARAMTER This or Buffer is NULL.=0D +=0D +**/=0D +EFI_STATUS=0D +EFIAPI=0D +SmramSaveStateReadRegisterByIndex (=0D + IN UINTN CpuIndex,=0D + IN UINTN RegisterIndex,=0D + IN UINTN Width,=0D + OUT VOID *Buffer=0D + )=0D +{=0D + if (RegisterIndex =3D=3D 0) {=0D + return EFI_NOT_FOUND;=0D + }=0D +=0D + if (SmramSaveStateGetRegisterLma () =3D=3D EFI_SMM_SAVE_STATE_REGISTER_L= MA_32BIT) {=0D + //=0D + // If 32-bit mode width is zero, then the specified register can not b= e accessed=0D + //=0D + if (mSmmSmramCpuWidthOffset[RegisterIndex].Width32 =3D=3D 0) {=0D + return EFI_NOT_FOUND;=0D + }=0D +=0D + //=0D + // If Width is bigger than the 32-bit mode width, then the specified r= egister can not be accessed=0D + //=0D + if (Width > mSmmSmramCpuWidthOffset[RegisterIndex].Width32) {=0D + return EFI_INVALID_PARAMETER;=0D + }=0D +=0D + //=0D + // Write return buffer=0D + //=0D + ASSERT (gSmst->CpuSaveState[CpuIndex] !=3D NULL);=0D + CopyMem (Buffer, (UINT8 *)gSmst->CpuSaveState[CpuIndex] + mSmmSmramCpu= WidthOffset[RegisterIndex].Offset32, Width);=0D + } else {=0D + //=0D + // If 64-bit mode width is zero, then the specified register can not b= e accessed=0D + //=0D + if (mSmmSmramCpuWidthOffset[RegisterIndex].Width64 =3D=3D 0) {=0D + return EFI_NOT_FOUND;=0D + }=0D +=0D + //=0D + // If Width is bigger than the 64-bit mode width, then the specified r= egister can not be accessed=0D + //=0D + if (Width > mSmmSmramCpuWidthOffset[RegisterIndex].Width64) {=0D + return EFI_INVALID_PARAMETER;=0D + }=0D +=0D + //=0D + // Write lower 32-bits of return buffer=0D + //=0D + CopyMem (Buffer, (UINT8 *)gSmst->CpuSaveState[CpuIndex] + mSmmSmramCpu= WidthOffset[RegisterIndex].Offset64Lo, MIN (4, Width));=0D + if (Width >=3D 4) {=0D + //=0D + // Write upper 32-bits of return buffer=0D + //=0D + CopyMem ((UINT8 *)Buffer + 4, (UINT8 *)gSmst->CpuSaveState[CpuIndex]= + mSmmSmramCpuWidthOffset[RegisterIndex].Offset64Hi, Width - 4);=0D + }=0D + }=0D +=0D + return EFI_SUCCESS;=0D +}=0D --=20 2.25.1