From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from NAM11-BN8-obe.outbound.protection.outlook.com (NAM11-BN8-obe.outbound.protection.outlook.com [40.107.236.40]) by mx.groups.io with SMTP id smtpd.web11.37944.1674099857644019386 for ; Wed, 18 Jan 2023 19:44:18 -0800 Authentication-Results: mx.groups.io; dkim=pass header.i=@amd.com header.s=selector1 header.b=j1E2mMP9; 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.236.40, mailfrom: abner.chang@amd.com) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=d7gPof57Tmd59arj/rDpzulQTadCtZdCWrUSHk1h8D4dpok1LPHK0XyRYcgH5AaNmHJPckg0bad/mbhoC3bohC6aaO8EbYHP3v7Ff33a5gA+gYLaoutwrCA5GAntSRgknOQBmkGURBzPwjq3gAPFEviFppVz1IFX/XFMzkg+wNwsaqu16VO9MPdZgoC9CLXDX9ubm4+04bASFHjaHHbxn15w80LVEoXyfjcYvi12CDy+Ep88iev/vetAi3t+IVVu1rq92gPlrIbKD0SneuhBcY5MaLCE+OPoOV4p4AhH6mol3O4zdz7TiWsumpeaV0rlAknRU23xPkAd328cdcufFA== 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=A3aCM0upNG9AEAzPb70dEzdW+dOPcKHnq38tmh5vqoc=; b=U+Wib6P4IFU6u8nCkbIPe31aIarUjCZcdoa2IDPX2d32jXqVvSYP1jU8AM/dLpyiaCSQbmWU+uFhbcTFUgibizdPOZSoB/uy+7jutuzko2UAHBz6TiWylp0g8/DqrE7ftqCQB/fWuDZrtT92uT3KELaU76qI1yx95X722/FRjxbOzABB6+A/m0CE/MereUKTtngIl+XXYKFqNrkJv4P4dKfhDMgaLpierugV2I+W8rXZfL3hhc2XtrRH5jLFutwaDcqTmFrAHwWWSaTjPU5m55QYJFxosx6iV5cIO1MhNR6dQM/wPsreql3xQ6c+wFcDhzzp6E0pCfj0QaUhXda96w== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=amd.com; dmarc=pass action=none header.from=amd.com; dkim=pass header.d=amd.com; 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=A3aCM0upNG9AEAzPb70dEzdW+dOPcKHnq38tmh5vqoc=; b=j1E2mMP9nrPZ12qtRqIxikNwJg77zb+YA4SR0C+KUEJuDL75v+xw0zg8URH1t71sjItISpUnnrsSIaGe+J+HOBNK4Vz7LDMW4ZSHySGWITVmUBkjM+45Eeo3XtoQeYX1lwasdYCqBP3Jtichqqjjt2GjMzg8NRzc8zMIYiM8ZoU= Received: from MN2PR12MB3966.namprd12.prod.outlook.com (2603:10b6:208:165::18) by BY5PR12MB4162.namprd12.prod.outlook.com (2603:10b6:a03:201::11) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6002.13; Thu, 19 Jan 2023 03:44:14 +0000 Received: from MN2PR12MB3966.namprd12.prod.outlook.com ([fe80::d606:ab63:cf3:5d36]) by MN2PR12MB3966.namprd12.prod.outlook.com ([fe80::d606:ab63:cf3:5d36%7]) with mapi id 15.20.6002.024; Thu, 19 Jan 2023 03:44:08 +0000 From: "Chang, Abner" To: "Attar, AbdulLateef (Abdul Lateef)" , "devel@edk2.groups.io" CC: "Attar, AbdulLateef (Abdul Lateef)" , "Grimes, Paul" , "Kirkendall, Garrett" , Eric Dong , Ray Ni , Rahul Kumar , Gerd Hoffmann , "Attar, AbdulLateef (Abdul Lateef)" Subject: Re: [PATCH v3 3/6] UefiCpuPkg: Implements SmmSmramSaveStateLib library class Thread-Topic: [PATCH v3 3/6] UefiCpuPkg: Implements SmmSmramSaveStateLib library class Thread-Index: AQHZK16BbE844gK8bEKyOOkryu9/eq6lGacA Date: Thu, 19 Jan 2023 03:44:08 +0000 Message-ID: References: In-Reply-To: Accept-Language: zh-CN, en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: msip_labels: MSIP_Label_4342314e-0df4-4b58-84bf-38bed6170a0f_Enabled=true; MSIP_Label_4342314e-0df4-4b58-84bf-38bed6170a0f_SetDate=2023-01-19T03:44:06Z; MSIP_Label_4342314e-0df4-4b58-84bf-38bed6170a0f_Method=Standard; MSIP_Label_4342314e-0df4-4b58-84bf-38bed6170a0f_Name=General; MSIP_Label_4342314e-0df4-4b58-84bf-38bed6170a0f_SiteId=3dd8961f-e488-4e60-8e11-a82d994e183d; MSIP_Label_4342314e-0df4-4b58-84bf-38bed6170a0f_ActionId=0c42d9c4-5105-45b0-a682-06c7d43ab81a; MSIP_Label_4342314e-0df4-4b58-84bf-38bed6170a0f_ContentBits=1 authentication-results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=amd.com; x-ms-publictraffictype: Email x-ms-traffictypediagnostic: MN2PR12MB3966:EE_|BY5PR12MB4162:EE_ x-ms-office365-filtering-correlation-id: 472015aa-e39f-4258-82c5-08daf9cf6bbe x-ms-exchange-senderadcheck: 1 x-ms-exchange-antispam-relay: 0 x-microsoft-antispam: BCL:0; x-microsoft-antispam-message-info: zEe//AKeR7I1HaYEPuy5tmqfGzqX9dCdIwTpRD7TELuW/9c8/H9ry0LEYaZTZ7+yBFkciLWgxXqjCFdrfq/p5HxA0UvPk7yF6XtvCYxl2sUZqK+qzKd8sw5RMGsRpjZ9fBhrA4ogcaTcVv40XMkgMIdJwrJPJn/ttFXZVDGfYcPebI/giN5Sg9NmfokgOtBeFkV8aAFg91qJvYo8VsgJngYx1ahk++D8pcdCLqc2Uz3whIDnrTN6jzKD/eATkc6C8Y7Pw28/xwugckPRyzGqH0oZMrqNYYodmk6t1RGpAUcKwhOWIGP6Z1aPMiV95OvRnTYvgXzmLsgckFdeHdwpdSpj9DL1+U8YW8w4FLpIjfRrnEu03Nk/473SnUFiGHYXWY4VwFvckSH2SWf+knGy+cxxhG4wnbW7LTQ7G6s8cv2cnAQaB9kOrrfbJ74M1Vd42qJ6y8gM6QINPzDIV/FPLtxsAQOgqSOjCtEfgnYOdD8HZNFTdxs1lNCQbiAaIafF1GZBS+TSUyAR708CAC9HPFcT7gT1Cn+dwS8dLmGAz7baHq85dHKFJCNKl36fQ/AVRYawkJO4DJqCWsrLiGF/g0aMA9k2x7gdLLS7gNr6/J+fftjfOO8sUKjjH3ZJbx9jNA0yByxjDoKmh4G71mz9l/BmhGK8Azqz37ttTO/QAZ9vwhCM3nGVznegf7qWKQmkTpfxRqExEwj9ruH9cgGyNnj0calKgnSc0BDYKs66tPlcgCeP0quBj0S+vgpaNqNU x-forefront-antispam-report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:MN2PR12MB3966.namprd12.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230022)(4636009)(376002)(366004)(39860400002)(396003)(346002)(136003)(451199015)(4326008)(38070700005)(41300700001)(33656002)(38100700002)(86362001)(478600001)(71200400001)(316002)(54906003)(110136005)(66946007)(26005)(186003)(7696005)(55016003)(966005)(76116006)(66446008)(8676002)(53546011)(66476007)(6506007)(9686003)(2906002)(64756008)(30864003)(83380400001)(66556008)(122000001)(5660300002)(52536014)(8936002)(213903007)(579004)(559001);DIR:OUT;SFP:1101; x-ms-exchange-antispam-messagedata-chunkcount: 1 x-ms-exchange-antispam-messagedata-0: =?us-ascii?Q?khAiktgkOBpsPFT8PiU1og4FWrlWmzzmNWSUrWYcIrZMaBqFrgyUGwiDoqxU?= =?us-ascii?Q?1vtMUsZK0Hg+PNpSGzDN+2YqB3V1TrWPN9vBoOYmBGQpdSe/w8xxVD+zmaQj?= =?us-ascii?Q?2pgq9N+GteU03D7fALQJXRN7+NtzvASjtHV6feppkzNKPLBD7jr7RVdMDIxZ?= =?us-ascii?Q?t5jTJeqEAESDWUpLd2Hg0fw1ZOz9ofXgrwkkS/gK5x3ASYnP1xu2UvTAtryD?= =?us-ascii?Q?VZefBKsJatb5TVgqaFgRaDRojZ7GCWYe8mbh9y8scrrUfByGKHPixiJC85Kg?= =?us-ascii?Q?S2VtNeOIrv3zhNZy1r4Srsm1oHcDCBoCRDhgdVcBPVgSp6BXQVcEDgfCC6nH?= =?us-ascii?Q?FSSvuxCFDDp6cc7ULQiFFN7Z6m1rB+AKy5S+5ytIRi/dkdOqmLZA0E4J+TmF?= =?us-ascii?Q?e9EGnbsLNqn7mxLrI8XEB/VdfIEdjIyxcYJmw2V2QAsdw2k1jFZFKulZy8wm?= =?us-ascii?Q?GNA+LRHn0JngvrREsXOnw/tKrG1aDieYdjr+2JFgynReO79uvXg6BZ8Dd5VO?= =?us-ascii?Q?Bg05ZFstSD2SWrju8pjStkcBgGyamkO6bBOkXGxTFDcCSA/osYoKH/Dlqdv+?= =?us-ascii?Q?tn9xLQvTwJXOTXV3SPXdTXYLPLvr5yTYEituf0Ko88s9gHpJwow2MjziOVrr?= =?us-ascii?Q?QF0BPJ6OztAgdgg9hqB1b5tdUJgjG7zL/dvZlC6vUHGWBMMZrftgI6yDW20a?= =?us-ascii?Q?h/rPntNZB1fls3i728tE5jEo93yuejMDX5gWXdm3BhjUd1yTidzULlPnryPW?= =?us-ascii?Q?15tFHEkTLNd+NqLbyA0J8uRysymLnCwnActoSK6R/Zl6OZSgzZrFHk/WvaDA?= =?us-ascii?Q?WN6UZP1d8jdmd/bwDVEUbq8pj2Hk8y5cP+QLjWlcuEaVJmWt79mcvED/OtHx?= =?us-ascii?Q?MkpX2DH1Eej7gDuNQfmy3tDZWdhGoYEwfltMG72TVtoQgukx9q4f7vQE3FdS?= =?us-ascii?Q?I9HSNVw/TOgplYC7IVFZTx6ro/5z/39TZ2QugvZ+qNVmmTjbtnPpGrQT+o+m?= =?us-ascii?Q?jM0CcVJn8Bn/vK3ZQeEM8Z4uDmseSqQssby4wYcCWexHY8q71u3UmvIkaW5B?= =?us-ascii?Q?Rv2ZTlOIpPpMQiuKdukvwFdYpTl38TwQj2aqQV5GWf9R2Oswiyrv+v9VeNVU?= =?us-ascii?Q?D7omx5GoazgeaddbJtyr8+mSfkZcNaBXUdiCHg5EQ/uob0W/DLFybwHKDn9W?= =?us-ascii?Q?OlD0rk3G6b7nID12UfogI9i+QMuIAgcsa7fYDdjRR0yNlORPuwxbC/LEQLKg?= =?us-ascii?Q?OmQlxAH+37vsg8JIEKBycTbL5wPUe5JiaLKAxKs2hWQdtCnqQsJ3KrwnUkd9?= =?us-ascii?Q?u9VFacQAOouRHYNDphR+owhjFeh2U+Wj+6FKplZrxNscJgTbOIbWW4V3TkfY?= =?us-ascii?Q?j7MCE9JMhnye8wXnxy/EGj0CUIp8Wu40o0jvekRQY2wnCugW8Fx9Vqia3r3/?= =?us-ascii?Q?RAauAxJtZaT8IzZkTv8XB9qDnmOBUR62rmoq11jXKZ63i6Qm/GFisI2KAik3?= =?us-ascii?Q?bissNDqSceh7Za8bK0PukNhmUO1DqPS3eDwjpXV5V8x2oEuTmoITDFfECdOG?= =?us-ascii?Q?sgk2xuQxt1f0WKfFHhozNHSz/jQVxXyq9UmQ5cna?= MIME-Version: 1.0 X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-AuthSource: MN2PR12MB3966.namprd12.prod.outlook.com X-MS-Exchange-CrossTenant-Network-Message-Id: 472015aa-e39f-4258-82c5-08daf9cf6bbe X-MS-Exchange-CrossTenant-originalarrivaltime: 19 Jan 2023 03:44:08.7071 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-mailboxtype: HOSTED X-MS-Exchange-CrossTenant-userprincipalname: 1aQWJlHuxRSgntbwXmPAK4KO+/vg06kZOA72HaNHN/VBZwLcKXKzjhGI+SGdfqAN6rq110s7RYrUq/kgDbdX4A== X-MS-Exchange-Transport-CrossTenantHeadersStamped: BY5PR12MB4162 Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable [AMD Official Use Only - General] Reviewed-by: Abner Chang > -----Original Message----- > From: Abdul Lateef Attar > Sent: Thursday, January 19, 2023 1:01 AM > To: devel@edk2.groups.io > Cc: Attar, AbdulLateef (Abdul Lateef) ; > Grimes, Paul ; Kirkendall, Garrett > ; Chang, Abner ; > Eric Dong ; Ray Ni ; Rahul Kumar > ; Gerd Hoffmann ; Attar, > AbdulLateef (Abdul Lateef) > Subject: [PATCH v3 3/6] UefiCpuPkg: Implements SmmSmramSaveStateLib > library class >=20 > From: Abdul Lateef Attar >=20 > BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=3D4182 >=20 > Implements SmmSmramSaveStateLib Library class for AMD cpu family. >=20 > Cc: Paul Grimes > Cc: Garrett Kirkendall > Cc: Abner Chang > Cc: Eric Dong > Cc: Ray Ni > Cc: Rahul Kumar > Cc: Gerd Hoffmann >=20 > Signed-off-by: Abdul Lateef Attar > --- > UefiCpuPkg/UefiCpuPkg.dsc | 3 + > .../AmdSmmSmramSaveStateLib.inf | 28 ++ > .../SmmSmramSaveStateLib/SmramSaveState.h | 102 ++++++ > .../SmmSmramSaveStateLib/AmdSmramSaveState.c | 319 > ++++++++++++++++++ > .../SmramSaveStateCommon.c | 124 +++++++ > 5 files changed, 576 insertions(+) > create mode 100644 > UefiCpuPkg/Library/SmmSmramSaveStateLib/AmdSmmSmramSaveStateLib. > inf > create mode 100644 > UefiCpuPkg/Library/SmmSmramSaveStateLib/SmramSaveState.h > create mode 100644 > UefiCpuPkg/Library/SmmSmramSaveStateLib/AmdSmramSaveState.c > create mode 100644 > UefiCpuPkg/Library/SmmSmramSaveStateLib/SmramSaveStateCommon.c >=20 > 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 # # Copyright (c) 2007 - 2022, Intel Corporation.= All > rights reserved.
+# Copyright (C) 2023 Advanced Micro Devices, Inc. A= ll > rights reserved.
# # SPDX-License-Identifier: BSD-2-Clause-Patent > #@@ -104,6 +105,7 @@ [LibraryClasses.common.DXE_SMM_DRIVER] >=20 > MemoryAllocationLib|MdePkg/Library/SmmMemoryAllocationLib/SmmMe > moryAllocationLib.inf HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf > CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/Smm > CpuExceptionHandlerLib.inf+ > SmmSmramSaveStateLib|UefiCpuPkg/Library/SmmSmramSaveStateLib/Am > dSmmSmramSaveStateLib.inf [LibraryClasses.common.MM_STANDALONE] > MmServicesTableLib|MdePkg/Library/StandaloneMmServicesTableLib/Stan > daloneMmServicesTableLib.inf@@ -191,6 +193,7 @@ [Components.IA32, > Components.X64] > > UnitTestResultReportLib|UnitTestFrameworkPkg/Library/UnitTestResultRep > ortLib/UnitTestResultReportLibConOut.inf }+ > UefiCpuPkg/Library/SmmSmramSaveStateLib/AmdSmmSmramSaveStateLib. > inf [Components.X64] > UefiCpuPkg/Library/CpuExceptionHandlerLib/UnitTest/DxeCpuExceptionHan > dlerLibUnitTest.infdiff --git > a/UefiCpuPkg/Library/SmmSmramSaveStateLib/AmdSmmSmramSaveStateLi > b.inf > b/UefiCpuPkg/Library/SmmSmramSaveStateLib/AmdSmmSmramSaveStateLi > b.inf > new file mode 100644 > index 000000000000..91f8927e0419 > --- /dev/null > +++ > b/UefiCpuPkg/Library/SmmSmramSaveStateLib/AmdSmmSmramSaveStateLi > b.in > +++ f > @@ -0,0 +1,28 @@ > +## @file+# SMM Smram save state service lib.+#+# This is SMM Smram > save state service lib that provide service to read and+# 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_N= AME > =3D AmdSmmSmramSaveStateLib+ FILE_GUID =3D FB7D0A60= -E8D4- > 4EFA-90AA-B357BC569879+ MODULE_TYPE =3D DXE_SMM_DRIVE= R+ > VERSION_STRING =3D 1.0+ LIBRARY_CLASS = =3D > SmmSmramSaveStateLib++[Sources]+ SmramSaveState.h+ > SmramSaveStateCommon.c+ AmdSmramSaveState.c++[Packages]+ > MdePkg/MdePkg.dec+ UefiCpuPkg/UefiCpuPkg.decdiff --git > a/UefiCpuPkg/Library/SmmSmramSaveStateLib/SmramSaveState.h > b/UefiCpuPkg/Library/SmmSmramSaveStateLib/SmramSaveState.h > new file mode 100644 > index 000000000000..c55ae004e016 > --- /dev/null > +++ b/UefiCpuPkg/Library/SmmSmramSaveStateLib/SmramSaveState.h > @@ -0,0 +1,102 @@ > +/** @file+ SMRAM Save State Map header file.++ Copyright (c) 2010 - 20= 19, > Intel Corporation. All rights reserved.
+ Copyright (C) 2023 Advanced > Micro Devices, Inc. All rights reserved.
+ SPDX-License-Identifier: B= SD-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_STATE_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 Leng= th;+} > CPU_SMM_SAVE_STATE_REGISTER_RANGE;++// Structure used to build a > lookup table to retrieve the widths and offsets+// 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+EFIAPI+SmramSaveStateGetRegisterLma (+ > VOID+ );++/**+ Read information from the CPU save state.++ @param > Register Specifies the CPU register to read form the save state.++ @ret= val 0 > Register is not valid+ @retval >0 Index into mSmmSmramCpuWidthOffset[] > associated with > Register++**/+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 relocation handler.++ > @param[in] CpuIndex Specifies the zero-based index of the CPU save > 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 value read from the save state.+= + > @retval EFI_SUCCESS The register was read from Save State.+ @r= etval > EFI_NOT_FOUND The register is not defined for the Save State 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+ );++#endifdiff --git > a/UefiCpuPkg/Library/SmmSmramSaveStateLib/AmdSmramSaveState.c > b/UefiCpuPkg/Library/SmmSmramSaveStateLib/AmdSmramSaveState.c > new file mode 100644 > index 000000000000..76e241c88953 > --- /dev/null > +++ b/UefiCpuPkg/Library/SmmSmramSaveStateLib/AmdSmramSaveState.c > @@ -0,0 +1,319 @@ > +/** @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_STATE_LOOKUP_ENTRY+#define > SMM_CPU_OFFSET(Field) OFFSET_OF (AMD_SMRAM_SAVE_STATE_MAP, > Field)++// Table used by SmramSaveStateGetRegisterIndex() to convert an > EFI_SMM_SAVE_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_STATE_REGISTER_LDTINFO),+ SMM_REGISTER_RANGE > (EFI_SMM_SAVE_STATE_REGISTER_ES, > EFI_SMM_SAVE_STATE_REGISTER_RIP),+ SMM_REGISTER_RANGE > (EFI_SMM_SAVE_STATE_REGISTER_RFLAGS, > EFI_SMM_SAVE_STATE_REGISTER_CR4),+ > { (EFI_SMM_SAVE_STATE_REGISTER)0, > (EFI_SMM_SAVE_STATE_REGISTER)0, 0}+};++// Lookup table used to > retrieve the widths and offsets associated with each+// 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 CPU Protocol.+ //+ { 4, 4, SMM_CPU_OFFSET > (x86.SMMRevId), SMM_CPU_OFFSET (x64.SMMRevId), 0, FALSE}, > // SMM_SAVE_STATE_REGISTER_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._GDTRBaseLoDword), SMM_CPU_OFFSET (x64._GDTRBaseHiDword), > FALSE}, // EFI_SMM_SAVE_STATE_REGISTER_GDTBASE =3D 4+ { 0, 8, 0, > SMM_CPU_OFFSET (x64._IDTRBaseLoDword), SMM_CPU_OFFSET > (x64._IDTRBaseLoDword), FALSE}, // > EFI_SMM_SAVE_STATE_REGISTER_IDTBASE =3D 5+ { 0, 8, 0, > SMM_CPU_OFFSET (x64._LDTRBaseLoDword), SMM_CPU_OFFSET > (x64._LDTRBaseLoDword), FALSE}, // > EFI_SMM_SAVE_STATE_REGISTER_LDTBASE =3D 6+ { 0, 2, 0, > SMM_CPU_OFFSET (x64._GDTRLimit), 0, FALSE}, = // > EFI_SMM_SAVE_STATE_REGISTER_GDTLIMIT =3D 7+ { 0, 2, 0, > SMM_CPU_OFFSET (x64._IDTRLimit), 0, FALSE}, = // > EFI_SMM_SAVE_STATE_REGISTER_IDTLIMIT =3D 8+ { 0, 4, 0, > SMM_CPU_OFFSET (x64._LDTRLimit), 0, FALSE}, = // > EFI_SMM_SAVE_STATE_REGISTER_LDTLIMIT =3D 9+ { 0, 0, 0, = 0, > 0, FALSE}, // EFI_SMM_SAVE_STATE_= REGISTER_LDTINFO > =3D 10+ { 4, 2, SMM_CPU_OFFSET (x86._ES), SMM_CPU_OFFSET (x64._ES), > 0, FALSE}, // EFI_SMM_SAVE_STATE_= REGISTER_ES =3D > 20+ { 4, 2, SMM_CPU_OFFSET (x86._CS), SMM_CPU_OFFSET (x64._CS), > 0, FALSE}, // EFI_SMM_SAVE_STATE_= REGISTER_CS =3D > 21+ { 4, 2, SMM_CPU_OFFSET (x86._SS), SMM_CPU_OFFSET (x64._SS), > 0, FALSE}, // EFI_SMM_SAVE_STATE_= REGISTER_SS =3D > 22+ { 4, 2, SMM_CPU_OFFSET (x86._DS), SMM_CPU_OFFSET (x64._DS), > 0, FALSE}, // EFI_SMM_SAVE_STATE_= REGISTER_DS =3D > 23+ { 4, 2, SMM_CPU_OFFSET (x86._FS), SMM_CPU_OFFSET (x64._FS), > 0, FALSE}, // EFI_SMM_SAVE_STATE_= REGISTER_FS =3D > 24+ { 4, 2, SMM_CPU_OFFSET (x86._GS), SMM_CPU_OFFSET (x64._GS), > 0, FALSE}, // EFI_SMM_SAVE_STATE_= REGISTER_GS =3D > 25+ { 0, 2, 0, SMM_CPU_OFFSET (x64._LDTR), = 0, FALSE}, > // EFI_SMM_SAVE_STATE_REGISTER_LDTR_SEL =3D 26+ { 0, 2, 0, > SMM_CPU_OFFSET (x64._TR), 0, FALSE}, = // > EFI_SMM_SAVE_STATE_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_STATE_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_STATE_REGISTER_DR6 =3D 29+ { 0, 8, 0, > SMM_CPU_OFFSET (x64._R8), SMM_CPU_OFFSET (x64._R8) = + 4, > TRUE}, // EFI_SMM_SAVE_STATE_REGISTER_R8 =3D 30+ { 0, 8, 0, > SMM_CPU_OFFSET (x64._R9), SMM_CPU_OFFSET (x64._R9) = + 4, > TRUE}, // EFI_SMM_SAVE_STATE_REGISTER_R9 =3D 31+ { 0, 8, 0, > SMM_CPU_OFFSET (x64._R10), SMM_CPU_OFFSET (x64._R10) = + 4, > TRUE}, // EFI_SMM_SAVE_STATE_REGISTER_R10 =3D 32+ { 0, 8, 0, > SMM_CPU_OFFSET (x64._R11), SMM_CPU_OFFSET (x64._R11) = + 4, > TRUE}, // EFI_SMM_SAVE_STATE_REGISTER_R11 =3D 33+ { 0, 8, 0, > SMM_CPU_OFFSET (x64._R12), SMM_CPU_OFFSET (x64._R12) = + 4, > TRUE}, // EFI_SMM_SAVE_STATE_REGISTER_R12 =3D 34+ { 0, 8, 0, > SMM_CPU_OFFSET (x64._R13), SMM_CPU_OFFSET (x64._R13) = + 4, > TRUE}, // EFI_SMM_SAVE_STATE_REGISTER_R13 =3D 35+ { 0, 8, 0, > SMM_CPU_OFFSET (x64._R14), SMM_CPU_OFFSET (x64._R14) = + 4, > TRUE}, // EFI_SMM_SAVE_STATE_REGISTER_R14 =3D 36+ { 0, 8, 0, > SMM_CPU_OFFSET (x64._R15), SMM_CPU_OFFSET (x64._R15) = + 4, > TRUE}, // EFI_SMM_SAVE_STATE_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_STATE_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_STATE_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_STATE_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_STATE_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_STATE_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_STATE_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_STATE_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_STATE_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_STATE_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_STATE_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_STATE_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_STATE_REGISTER_CR3 =3D 53+ { 0, 8, 0, > SMM_CPU_OFFSET (x64._CR4), SMM_CPU_OFFSET (x64._CR4) = + 4, > FALSE}, // EFI_SMM_SAVE_STATE_REGISTER_CR4 =3D 54+ { 0, 0, 0, > 0, 0 }+};++/**+ Read an SMM Save= State register on the > target processor. If this function+ 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 state.+ @param[out] Buffer Upon retur= n, > this holds the CPU register value read+ from the s= ave state.++ > @retval EFI_SUCCESS The register was read from Save State.+ @r= etval > EFI_INVALID_PARAMTER Buffer is NULL.+ @retval EFI_UNSUPPORTED > This function does not support reading Register.+ @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[CpuIndex];++ > // 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_SMMREVID_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] i= s > valid or not using bit 1.+ if (!(CpuSaveState->x64.IO_DWord & 0x02u)) = {+ > return EFI_NOT_FOUND;+ }++ // Zero the IoInfo structure that will b= e > 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 & 0x= 01u) {+ > 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) || (IoInfo- > >IoType =3D=3D EFI_SMM_SAVE_STATE_IO_TYPE_OUTPUT)) {+ > SmramSaveStateReadRegister (CpuIndex, > EFI_SMM_SAVE_STATE_REGISTER_RAX, DataWidth, &IoInfo- > >IoData);+ }++ return EFI_SUCCESS;+ }++ // Convert Register to a = register > lookup table index+ return SmramSaveStateReadRegisterByIndex > (CpuIndex, SmramSaveStateGetRegisterIndex (Register), Width, > Buffer);+}++/**+ Writes an SMM Save State register on the target process= or. > If this function+ returns EFI_UNSUPPORTED, then the caller is responsibl= e > 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 Sys= tem > Management System Table (SMST).+ @param[in] Register The SMM Save > State register to write.+ @param[in] Width The number of bytes to wr= ite > to the CPU save state.+ @param[in] Buffer Upon entry, this holds the = new > CPU register value.++ @retval EFI_SUCCESS The register was wri= tten to > Save State.+ @retval EFI_INVALID_PARAMTER Buffer is NULL.+ @retval > EFI_UNSUPPORTED This function does not support writing Register.+ > @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;+ }++ CpuSaveSta= te =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_LMA_32BIT) {+ //+ // If 32-bit mode > width is zero, then the specified register can not be accessed+ //+ = if > (mSmmSmramCpuWidthOffset[RegisterIndex].Width32 =3D=3D 0) {+ return > EFI_NOT_FOUND;+ }++ //+ // If Width is bigger than the 32-bit mo= de > width, then the specified register can not be accessed+ //+ if (Wid= th > > 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 reg= ister can > not be accessed+ //+ if > (mSmmSmramCpuWidthOffset[RegisterIndex].Width64 =3D=3D 0) {+ return > EFI_NOT_FOUND;+ }++ //+ // If Width is bigger than the 64-bit mo= de > width, then the specified register can not be accessed+ //+ if (Wid= th > > mSmmSmramCpuWidthOffset[RegisterIndex].Width64) {+ return > EFI_INVALID_PARAMETER;+ }++ //+ // Write lower 32-bits of SMM St= ate > 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[RegisterIndex].Offset64Hi, (UINT8 *)Buffer + > 4, Width - 4);+ }+ }++ return EFI_SUCCESS;+}++/**+ Returns LMA valu= e of > the Processor.++ @param[in] VOID++ @retval UINT8 returns LMA bit > value.+**/+UINT8+EFIAPI+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 right= s > 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 > Register++**/+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; > mSmmSmramCpuRegisterRanges[Index].Length !=3D 0; Index++) {+ if > ((Register >=3D mSmmSmramCpuRegisterRanges[Index].Start) && (Register <= =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 relocation handler.+= + > @param[in] CpuIndex Specifies the zero-based index of the CPU save > 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 value read from the save state.+= + > @retval EFI_SUCCESS The register was read from Save State.+ @r= etval > EFI_NOT_FOUND The register is not defined for the Save State 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_LMA_32BIT) {+ //+ // If 32-bit mode > width is zero, then the specified register can not be accessed+ //+ = if > (mSmmSmramCpuWidthOffset[RegisterIndex].Width32 =3D=3D 0) {+ return > EFI_NOT_FOUND;+ }++ //+ // If Width is bigger than the 32-bit mo= de > width, then the specified register can not be accessed+ //+ if (Wid= th > > mSmmSmramCpuWidthOffset[RegisterIndex].Width32) {+ return > EFI_INVALID_PARAMETER;+ }++ //+ // Write return buffer+ //+ > ASSERT (gSmst->CpuSaveState[CpuIndex] !=3D NULL);+ CopyMem (Buffer, > (UINT8 *)gSmst->CpuSaveState[CpuIndex] + > mSmmSmramCpuWidthOffset[RegisterIndex].Offset32, Width);+ } else {+ > //+ // If 64-bit mode width is zero, then the specified register can n= ot be > 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 register 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] + > mSmmSmramCpuWidthOffset[RegisterIndex].Offset64Lo, MIN (4, Width));+ > if (Width >=3D 4) {+ //+ // Write upper 32-bits of return buffe= r+ //+ > CopyMem ((UINT8 *)Buffer + 4, (UINT8 *)gSmst->CpuSaveState[CpuIndex] > + mSmmSmramCpuWidthOffset[RegisterIndex].Offset64Hi, Width - > 4);+ }+ }++ return EFI_SUCCESS;+}-- > 2.25.1