From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from NAM11-CO1-obe.outbound.protection.outlook.com (NAM11-CO1-obe.outbound.protection.outlook.com [40.107.220.74]) by mx.groups.io with SMTP id smtpd.web11.159298.1673843773455768410 for ; Sun, 15 Jan 2023 20:36:13 -0800 Authentication-Results: mx.groups.io; dkim=pass header.i=@amd.com header.s=selector1 header.b=Um3nB0TK; 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.220.74, mailfrom: abdullateef.attar@amd.com) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=GyPJjF9NYvy6vL0iXsW6G4OZeCq5Qsb/Zw7lkjiD+5iYVn1HGnuV06sIkhOUfaUW/+6+QRLuacwxqCTAq9+LsoRUH2nSmRudk/bYe0faMs38PRlV4zV/I1+77l31ZzWVVlqwftDwsOpaPLDRObMw7P9snf3qH16YufbzaiPiDrYP7v/6YeefQhUYb2OXC1t2p5XdRnK9h1spQqT6/ckAWvFJnprnAYqINdl9R/JJujJ3OLeIXg9e+AhEItQ/aSvks9Yy8DJ3cfvPT08v00qsNGbTZL5GidCX9WwruGf6yfNODVxDe2wRyQdhEL4XDOR2LfWmBPMnzy0DYnZ5rptkAw== 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=sIeypxA4Z4ZbkEFPG3DuDSv56S1wJ5gdNbp6xl/ipXE=; b=oCZP2dfuKpNpnY5ueqZiSfGhtg+kDPrlEnuCuWB4Ux6DZb6Cna8hy0NYPAT8jQ/ykLcO40SV4sSW+eSr9N+Vw5zmrYI7BQVl3C0WT22gDJmXtF3OWQ5Xsl94Gw9uho4N+EoXTHjDUVl0hzlxfN2Cq3Ze8YFhyK4oLS++HXkr6OdMOb5VPl/kUnWSH9YoCryPEMrvWjT+PjDugk47cVEJFdOFcB7gmcPXD5DUAeOL7hDu5mhsGEf/eKtYcz7kVZuu6Ijga95HugauuBu//TmWDTwMrqMWYjwEZ7zHH+UeasXcAQHHq0HuvQaglrbNRmwVPnoLiwllz0M7b2vBBYBOgg== 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=sIeypxA4Z4ZbkEFPG3DuDSv56S1wJ5gdNbp6xl/ipXE=; b=Um3nB0TKo3UUVJVxJ5yN2yl1Rd3CpsXqNo0QMcIOpve1KEHuBK0VleNTDcSvPe5/r91Z09jA5RtbGfkpsFBVNWgJNiec2+wJPqEM2n3DO4BYo3f6ZI/7Hr3GutbcdqNV1h7pcjKCJVxXJBWIVkBXHbVf9QPWRQrjuRRvfkK7lE8= Received: from IA1PR12MB6458.namprd12.prod.outlook.com (2603:10b6:208:3aa::22) by DM4PR12MB5938.namprd12.prod.outlook.com (2603:10b6:8:69::9) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6002.13; Mon, 16 Jan 2023 04:36:07 +0000 Received: from IA1PR12MB6458.namprd12.prod.outlook.com ([fe80::54:ad09:aa9e:b2fa]) by IA1PR12MB6458.namprd12.prod.outlook.com ([fe80::54:ad09:aa9e:b2fa%6]) with mapi id 15.20.5986.023; Mon, 16 Jan 2023 04:36:01 +0000 From: "Attar, AbdulLateef (Abdul Lateef)" To: "Chang, Abner" , "devel@edk2.groups.io" CC: "Grimes, Paul" , "Kirkendall, Garrett" , Eric Dong , Ray Ni , Rahul Kumar , Gerd Hoffmann Subject: Re: [edk2-devel] [PATCH v2 4/6] UefiCpuPkg: Implements SmmSmramSaveStateLib library class Thread-Topic: [edk2-devel] [PATCH v2 4/6] UefiCpuPkg: Implements SmmSmramSaveStateLib library class Thread-Index: AQHZJYRyH+hKfq/rs0a7XQnXUDpfdK6e7UIAgAGNmWA= Date: Mon, 16 Jan 2023 04:36:01 +0000 Message-ID: References: In-Reply-To: Accept-Language: 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-15T04:45: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=e95c913c-aa82-4fe5-82e4-19921f2e36f5; 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: IA1PR12MB6458:EE_|DM4PR12MB5938:EE_ x-ms-office365-filtering-correlation-id: 297bc665-2eca-4eb0-18fb-08daf77b2b96 x-ms-exchange-senderadcheck: 1 x-ms-exchange-antispam-relay: 0 x-microsoft-antispam: BCL:0; x-microsoft-antispam-message-info: kWmakCkjzJ5IpKLu/KFbdjVT3AkzOwXFQNuzFUTSjPYCTYslP1T2ZQhnvQo8RyIEpBZQgFoyfT3vx/v/SqTs5pAPVdE29nyBZmtObWNvKjLldp7blQaRqu9tDpM6WjRRuO3qyCLjl0BvPGUy0t+ebnjiFWGdsuIZk01s3WEqKokCR6G9TGJDRxyrJkVISjek8mmkoOK76TRWFbLl1Z9lbDFM/2qGsX7vQftMo4k9zlg3Kg3ngq2AEqCInx2YqEz7JKb3r1Fu/kUOVXNANvmUlvfqB9zwDOoArA0e9RUZMtSS3y8FNtouJxSCXtikGg2lu+xs5Zsz4f3KAT3UNIVcCD/FT/4DgvT8snw/OFkKI6QPoPGNoUNhiBDnjwOOtp7HQSuV2BCfztJCSmcyheLCGEGigm+N2PWPQrntNUeyM5VDQvQ/1IMCZnOvifqeqO5jYWkEQ2jWWWd3LCJEs8PIw9yHT5/86ZXXqjiO0Q7j/wI/SD95cZJNYrDSrEUxgApmgpq+D9DmZ94mUb+lMjIXvS/hHxZZ8ZLDv9h605RsAYUSyzHxkuTwpejaCPzvOSLl/a56MhCDU/pectxdHo8gI90Ph5RapKqyeRXue2UTO/qSqqwVaGtIJxNJCQTEwaRT2WQ583acPXMCB7yV/cQCTb6YeO/qNLk6eFtikM9o5nqc1kKRVT2HAF0Ll8wXWabUQRNP5cc1UXGMvyT4np3lZQsAAB2X/Lfzd8rJecy9pGKoNzS/P7wahIyPB3Dkz7ra x-forefront-antispam-report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:IA1PR12MB6458.namprd12.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230022)(4636009)(376002)(136003)(366004)(346002)(396003)(39860400002)(451199015)(33656002)(38070700005)(122000001)(86362001)(2906002)(5660300002)(8936002)(38100700002)(30864003)(55016003)(41300700001)(83380400001)(52536014)(54906003)(110136005)(45080400002)(66899015)(478600001)(6506007)(53546011)(8676002)(316002)(7696005)(76116006)(66556008)(66946007)(66446008)(4326008)(66476007)(966005)(9686003)(71200400001)(64756008)(26005)(186003)(213903007)(559001)(579004);DIR:OUT;SFP:1101; x-ms-exchange-antispam-messagedata-chunkcount: 1 x-ms-exchange-antispam-messagedata-0: =?us-ascii?Q?KivpLo7a4KicluWIWZXwXwTQunNIeqwjmx+kWVSvD9H+cC+zETyk3K/vLvyl?= =?us-ascii?Q?vK4JQ64q20+mPZ0FkVsOQ6WfEfCl+ANXPyfSkSGDCBb3dzDTS7uEafMFSvqL?= =?us-ascii?Q?LfeP9XBPpreCLFP8ngJvtS6SZfTYmmR0PCs+iKoMbGO0N9YPl1DNBNkBkwDz?= =?us-ascii?Q?3Xi68A6iFdZSwDry623CJDafibA1sKfxJg9xSjwaW6SJq74WlAA6Tqf1rc5E?= =?us-ascii?Q?6O9W5v27mNnjqMdofEIdIB/y9jYJb8W/cLQbitKEQ7ipoLvg2Zf/b0BrycgH?= =?us-ascii?Q?ypd1DqVJmM1OI1vEAWBrAI0oPSRPtjeQ6gSX1Rj083yvAm3KyyOh5mj1PxLw?= =?us-ascii?Q?eUteuNgANE2nDqQgPL+rszgvZzJHItxopS8DGF7rAuAx4m5berGv1wsJd5RY?= =?us-ascii?Q?tF4UojvSLAMtWvPuR42uOhzzy81wbPYZRm0tVv03SPoLPJjKO3WxedxGI5W4?= =?us-ascii?Q?MGJ8CZRt1obPUg2/GS/vnSiouKskuVIv2OAnv8iGiBQcL/5sMDWBZgB3Q6ox?= =?us-ascii?Q?Gaosp4edErom2lmEBIdsU2nI/KLYSKFNwD14VL5M/LXRku45X+1Axu7hg1He?= =?us-ascii?Q?dd0cpHHoewIRfeKzhonkp+IxRg2L1gJ+FfP3N5zNN9u1br4XTsXQN/3fXm0o?= =?us-ascii?Q?a28BWkbMKHwSjbRdYVaRV6yIFLVWCmk6Fa1fz0aOhbLG40pNlpoMv14Xrdlx?= =?us-ascii?Q?53TDOO5an/ucy1QdKob3sbJqO/uTYDbiiiy/s2XHIXCpTFf1tauekftpz9K9?= =?us-ascii?Q?cPYlISEO+C0KUwrtIadmm0rBkLjc6FhyU2cwFJtamC7pHj1Q2cBK8NAQgqaQ?= =?us-ascii?Q?hGqMIqgAn5nRTcA15W3/QMJuZEjc9kuYgwSdDq8WZkTf153sRKc1FfxEUGgO?= =?us-ascii?Q?j7mQhTODO7RwAGUN0LSN8DpuFG2F3DdqTQUxesV+AEvOLRQ4Cte6QsICN9Dl?= =?us-ascii?Q?G4mFL6jXvOGZE6k+l2ph43y9kMtd12J0Zexb/9TcUdGqBa6kEV+Yyd90/MuL?= =?us-ascii?Q?v2czDSBFB2mHU+ZFVBaAbmhO1GzUAb8AClvJgyacakzHdXE6Aiy/o11JiUxF?= =?us-ascii?Q?4yuv6yqAUbrUji5W/zA11kfbIXnjOCka1AB/YOx20rCzP7zGvdUAwHGNlvhx?= =?us-ascii?Q?UVy4ww/+BEWttFDnFu69pRFLjjr1XziRRUwc+Fuwm4evq9IgzUbc0/9twxB7?= =?us-ascii?Q?hbCdYWoPwwLYhpJT+117P/hySEiK1sZzOnWamC3P/l7+tZzQKfhLDDfbpmC6?= =?us-ascii?Q?iANKwsxWf/7mD6wYvNU0Gf/n+lg02kKdHlA+bxgu52Mg2BMqivJGVcjfXBwv?= =?us-ascii?Q?gWVsCTmzaHKtnG59p2XaK4oEEPC8KVetWo1CR2KfIV7dHL8A/Ds/e38mbyDp?= =?us-ascii?Q?MhRaEMjR+IPMKVgP0VDgl+CjYQFeLsHxA/lEUXrtsQyaytXrpanbChHKZdDr?= =?us-ascii?Q?HhHB3fgWqnwCVnlDILaaUTkL5opqWfGHi7GScQZvnEpbK9cIzKOf1zU1d6Gp?= =?us-ascii?Q?eyTDWgR0RQSWcS2TnwvmeXTgezBEpD4S+7LoOAmzFiqUihEwyOKkI59W8QUC?= =?us-ascii?Q?jx04243KSSEcKtHM0ztQOy2Ioz987fFIiu57u7i9?= MIME-Version: 1.0 X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-AuthSource: IA1PR12MB6458.namprd12.prod.outlook.com X-MS-Exchange-CrossTenant-Network-Message-Id: 297bc665-2eca-4eb0-18fb-08daf77b2b96 X-MS-Exchange-CrossTenant-originalarrivaltime: 16 Jan 2023 04:36:01.0172 (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: 6vPFCtc+lVC8q4iOJxNjacyAwsFHAtqrI7NO743evEKflZAGOeVHbZukpWD4y4u1dczH4L+nhGpiC7zB7pSkhg== X-MS-Exchange-Transport-CrossTenantHeadersStamped: DM4PR12MB5938 Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Hi Abner, Please see inline for my reply under [Abdul]. Thanks AbduL -----Original Message----- From: Chang, Abner =20 Sent: 15 January 2023 10:15 To: devel@edk2.groups.io; Attar, AbdulLateef (Abdul Lateef) Cc: Grimes, Paul ; Kirkendall, Garrett ; Eric Dong ; Ray Ni ; = Rahul Kumar ; Gerd Hoffmann Subject: RE: [edk2-devel] [PATCH v2 4/6] UefiCpuPkg: Implements SmmSmramSav= eStateLib library class [AMD Official Use Only - General] According to the section 4.2.3 in edk2 c coding standard spec in below link= , the processor vendor directory must be under the processor arch directory= . We use vendor directory because the different implementations of the same= processor arch. https://tianocore-docs.github.io/edk2-CCodingStandardsSpecification/draft/e= dk2-CCodingStandardsSpecification-draft.pdf So for this case, we can just have AmdSmramSaveState.c under SmramSaveState= Lib\ according to the file naming defined in 4.3.5.4 because this library i= s only for X86 platform.=20 [Abdul] SmramSaveState.c will be different for Intel's implementation, that= 's the reason added Amd directory. After this patch set is reviewed and merged, we should have another patch s= et to update PiSmmCpuDxeSmm to use this library for SMM register access, re= move the one in SmmCpuFeaturelib. Also update OVMF to use SmmSmramSaveState= Lib. Migration SmmSaveState.c under PiSmmCpuDxeSmm to SmmSmramSaveStateLib = for Intel implementation. SmmSmramSaveStateLib implementation is AMD processor specific. I haven't added Intel's implementation, hence cant use this library in PiSm= mCpuDxeSmm until Intel's implementation added. Same applies to the OVMF. Other comments in below,=20 > -----Original Message----- > From: devel@edk2.groups.io On Behalf Of Abdul=20 > Lateef Attar via groups.io > Sent: Wednesday, January 11, 2023 2:16 PM > To: devel@edk2.groups.io > Cc: Attar, AbdulLateef (Abdul Lateef) ;=20 > Grimes, Paul ; Kirkendall, Garrett=20 > ; Chang, Abner ; Eric=20 > Dong ; Ray Ni ; Rahul Kumar=20 > ; Gerd Hoffmann ; Attar,=20 > AbdulLateef (Abdul Lateef) > Subject: [edk2-devel] [PATCH v2 4/6] UefiCpuPkg: Implements=20 > SmmSmramSaveStateLib library class >=20 > Caution: This message originated from an External Source. Use proper=20 > caution when opening attachments, clicking links, or responding. >=20 >=20 > From: Abdul Lateef Attar >=20 > BZ: > https://nam11.safelinks.protection.outlook.com/?url=3Dhttps%3A%2F%2Fbugz > illa.tianocore.org%2Fshow_bug.cgi%3Fid%3D4182&data=3D05%7C01%7Cabner. > chang%40amd.com%7C21622ff06cd949cc7e1608daf39b82a2%7C3dd8961fe48 > 84e608e11a82d994e183d%7C0%7C0%7C638090146492954852%7CUnknown% > 7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haW > wiLCJXVCI6Mn0%3D%7C3000%7C%7C%7C&sdata=3DQgHzNdcBkpCNbjGLPfx0L > Em6ECHYowjuSryyNiWf0ww%3D&reserved=3D0 >=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/Amd/SmramSaveState.c | 318 > ++++++++++++++++++ > .../SmramSaveStateCommon.c | 124 +++++++ > 5 files changed, 575 insertions(+) > create mode 100644 > UefiCpuPkg/Library/SmmSmramSaveStateLib/AmdSmmSmramSaveStateLib. > inf > create mode 100644 > UefiCpuPkg/Library/SmmSmramSaveStateLib/SmramSaveState.h > create mode 100644 > UefiCpuPkg/Library/SmmSmramSaveStateLib/Amd/SmramSaveState.c > create mode 100644 > UefiCpuPkg/Library/SmmSmramSaveStateLib/SmramSaveStateCommon.c >=20 > diff --git a/UefiCpuPkg/UefiCpuPkg.dsc b/UefiCpuPkg/UefiCpuPkg.dsc=20 > index f9a46089d2c7..99f7532ce00b 100644 > --- a/UefiCpuPkg/UefiCpuPkg.dsc > +++ b/UefiCpuPkg/UefiCpuPkg.dsc > @@ -2,6 +2,7 @@ > # UefiCpuPkg Package >=20 > # >=20 > # Copyright (c) 2007 - 2022, Intel Corporation. All rights=20 > reserved.
>=20 > +# Copyright (C) 2023 Advanced Micro Devices, Inc. All rights=20 > +reserved.
>=20 > # >=20 > # SPDX-License-Identifier: BSD-2-Clause-Patent >=20 > # >=20 > @@ -104,6 +105,7 @@ [LibraryClasses.common.DXE_SMM_DRIVER] >=20 > MemoryAllocationLib|MdePkg/Library/SmmMemoryAllocationLib/SmmMe > moryAllocationLib.inf >=20 > HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf >=20 >=20 > CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/Smm > CpuExceptionHandlerLib.inf >=20 > + > + > SmmSmramSaveStateLib|UefiCpuPkg/Library/SmmSmramSaveStateLib/Am > dSmmSmr > + amSaveStateLib.inf >=20 >=20 >=20 > [LibraryClasses.common.MM_STANDALONE] >=20 >=20 > MmServicesTableLib|MdePkg/Library/StandaloneMmServicesTableLib/Stan > daloneMmServicesTableLib.inf >=20 > @@ -191,6 +193,7 @@ [Components.IA32, Components.X64] > >=20 >=20 > UnitTestResultReportLib|UnitTestFrameworkPkg/Library/UnitTestResultRep > ortLib/UnitTestResultReportLibConOut.inf >=20 > } >=20 > + > UefiCpuPkg/Library/SmmSmramSaveStateLib/AmdSmmSmramSaveStateLib. > inf >=20 >=20 >=20 > [Components.X64] >=20 >=20 > UefiCpuPkg/Library/CpuExceptionHandlerLib/UnitTest/DxeCpuExceptionHan > dlerLibUnitTest.inf >=20 > diff --git > a/UefiCpuPkg/Library/SmmSmramSaveStateLib/AmdSmmSmramSaveStateLi > b.inf > b/UefiCpuPkg/Library/SmmSmramSaveStateLib/AmdSmmSmramSaveStateLi > b.inf > new file mode 100644 > index 000000000000..463e4c9331be > --- /dev/null > +++ > b/UefiCpuPkg/Library/SmmSmramSaveStateLib/AmdSmmSmramSaveStateLi > b.in > +++ f > @@ -0,0 +1,28 @@ > +## @file >=20 > +# SMM Smram save state service lib. >=20 > +# >=20 > +# This is SMM Smram save state service lib that provide service to=20 > +read and >=20 > +# save savestate area registers. >=20 > +# >=20 > +# Copyright (C) 2023 Advanced Micro Devices, Inc. All rights=20 > +reserved.
>=20 > +# >=20 > +# SPDX-License-Identifier: BSD-2-Clause-Patent >=20 > +# >=20 > +## >=20 > + >=20 > +[Defines] >=20 > + INF_VERSION =3D 1.29 >=20 > + BASE_NAME =3D AmdSmmSmramSaveStateLib >=20 > + FILE_GUID =3D FB7D0A60-E8D4-4EFA-90AA-B357BC56987= 9 >=20 > + MODULE_TYPE =3D DXE_SMM_DRIVER >=20 > + VERSION_STRING =3D 1.0 >=20 > + LIBRARY_CLASS =3D SmmSmramSaveStateLib >=20 > + >=20 > +[Sources] >=20 > + SmramSaveState.h >=20 > + SmramSaveStateCommon.c >=20 > + Amd/SmramSaveState.c >=20 > + >=20 > +[Packages] >=20 > + MdePkg/MdePkg.dec >=20 > + UefiCpuPkg/UefiCpuPkg.dec >=20 > diff --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 >=20 > + SMRAM Save State Map header file. >=20 > + >=20 > + Copyright (c) 2010 - 2019, Intel Corporation. All rights=20 > + reserved.
>=20 > + Copyright (C) 2023 Advanced Micro Devices, Inc. All rights=20 > + reserved.
>=20 > + SPDX-License-Identifier: BSD-2-Clause-Patent >=20 > + >=20 > +**/ >=20 > + >=20 > +#ifndef SMRAM_SAVESTATE_H_ >=20 > +#define SMRAM_SAVESTATE_H_ >=20 > + >=20 > +#include >=20 > +#include >=20 > +#include >=20 > +#include >=20 > +#include >=20 > +#include >=20 > + >=20 > +// EFER register LMA bit >=20 > +#define LMA BIT10 >=20 > + >=20 > +// Macro used to simplify the lookup table entries of type=20 > +CPU_SMM_SAVE_STATE_REGISTER_RANGE >=20 > +#define SMM_REGISTER_RANGE(Start, End) { Start, End, End - Start + 1=20 > +} >=20 > + >=20 > +#define SMM_SAVE_STATE_REGISTER_MAX_INDEX 2 >=20 > + >=20 > +// Structure used to describe a range of registers >=20 > +typedef struct { >=20 > + EFI_SMM_SAVE_STATE_REGISTER Start; >=20 > + EFI_SMM_SAVE_STATE_REGISTER End; >=20 > + UINTN Length; >=20 > +} CPU_SMM_SAVE_STATE_REGISTER_RANGE; >=20 > + >=20 > +// Structure used to build a lookup table to retrieve the widths and=20 > +offsets >=20 > +// associated with each supported EFI_SMM_SAVE_STATE_REGISTER value >=20 > + >=20 > +typedef struct { >=20 > + UINT8 Width32; >=20 > + UINT8 Width64; >=20 > + UINT16 Offset32; >=20 > + UINT16 Offset64Lo; >=20 > + UINT16 Offset64Hi; >=20 > + BOOLEAN Writeable; >=20 > +} CPU_SMM_SAVE_STATE_LOOKUP_ENTRY; >=20 > + >=20 > +/** >=20 > + Returns LMA value of the Processor. >=20 > + >=20 > + @param[in] VOID >=20 > + >=20 > + @retval UINT8 returns LMA bit value. >=20 > +**/ >=20 > +UINT8 >=20 > +EFIAPI >=20 > +SmramSaveStateGetRegisterLma ( >=20 > + VOID >=20 > + ); >=20 > + >=20 > +/** >=20 > + Read information from the CPU save state. >=20 > + >=20 > + @param Register Specifies the CPU register to read form the save sta= te. >=20 > + >=20 > + @retval 0 Register is not valid >=20 > + @retval >0 Index into mSmmSmramCpuWidthOffset[] associated with=20 > + Register >=20 > + >=20 > +**/ >=20 > +UINTN >=20 > +EFIAPI >=20 > +SmramSaveStateGetRegisterIndex ( >=20 > + IN EFI_SMM_SAVE_STATE_REGISTER Register >=20 > + ); >=20 > + >=20 > +/** >=20 > + Read a CPU Save State register on the target processor. >=20 > + >=20 > + This function abstracts the differences that whether the CPU Save=20 > + State register is in the >=20 > + IA32 CPU Save State Map or X64 CPU Save State Map. >=20 > + >=20 > + This function supports reading a CPU Save State register in SMBase > relocation handler. >=20 > + >=20 > + @param[in] CpuIndex Specifies the zero-based index of the CPU s= ave > state. >=20 > + @param[in] RegisterIndex Index into mSmmSmramCpuWidthOffset[] > look up table. >=20 > + @param[in] Width The number of bytes to read from the CPU sa= ve > state. >=20 > + @param[out] Buffer Upon return, this holds the CPU register va= lue > read from the save state. >=20 > + >=20 > + @retval EFI_SUCCESS The register was read from Save State. >=20 > + @retval EFI_NOT_FOUND The register is not defined for the Save > State of Processor. >=20 > + @retval EFI_INVALID_PARAMTER This or Buffer is NULL. >=20 > + >=20 > +**/ >=20 > +EFI_STATUS >=20 > +EFIAPI >=20 > +SmramSaveStateReadRegisterByIndex ( >=20 > + IN UINTN CpuIndex, >=20 > + IN UINTN RegisterIndex, >=20 > + IN UINTN Width, >=20 > + OUT VOID *Buffer >=20 > + ); >=20 > + >=20 > +#endif >=20 > 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 >=20 > +Provides services to access SMRAM Save State Map >=20 > + >=20 > +Copyright (c) 2010 - 2019, Intel Corporation. All rights=20 > +reserved.
>=20 > +Copyright (C) 2023 Advanced Micro Devices, Inc. All rights=20 > +reserved.
>=20 > +SPDX-License-Identifier: BSD-2-Clause-Patent >=20 > + >=20 > +**/ >=20 > + >=20 > +#include "SmramSaveState.h" >=20 > +#include >=20 > +#include >=20 > + >=20 > +#define EFER_ADDRESS 0XC0000080ul >=20 > +#define SMM_SAVE_STATE_REGISTER_SMMREVID_INDEX 1 >=20 > + >=20 > +// Macro used to simplify the lookup table entries of type=20 > +CPU_SMM_SAVE_STATE_LOOKUP_ENTRY >=20 > +#define SMM_CPU_OFFSET(Field) OFFSET_OF > (AMD_SMRAM_SAVE_STATE_MAP, > +Field) >=20 > + >=20 > +// Table used by SmramSaveStateGetRegisterIndex() to convert an=20 > +EFI_SMM_SAVE_STATE_REGISTER >=20 > +// value to an index into a table of type=20 > +CPU_SMM_SAVE_STATE_LOOKUP_ENTRY >=20 > +CONST CPU_SMM_SAVE_STATE_REGISTER_RANGE > mSmmSmramCpuRegisterRanges[] =3D > +{ >=20 > + SMM_REGISTER_RANGE (EFI_SMM_SAVE_STATE_REGISTER_GDTBASE, > + EFI_SMM_SAVE_STATE_REGISTER_LDTINFO), >=20 > + SMM_REGISTER_RANGE (EFI_SMM_SAVE_STATE_REGISTER_ES, > EFI_SMM_SAVE_STATE_REGISTER_RIP), >=20 > + SMM_REGISTER_RANGE (EFI_SMM_SAVE_STATE_REGISTER_RFLAGS, > + EFI_SMM_SAVE_STATE_REGISTER_CR4), >=20 > + { (EFI_SMM_SAVE_STATE_REGISTER)0, > (EFI_SMM_SAVE_STATE_REGISTER)0, 0} >=20 > +}; >=20 > + >=20 > +// Lookup table used to retrieve the widths and offsets associated=20 > +with each >=20 > +// supported EFI_SMM_SAVE_STATE_REGISTER value >=20 > +CONST CPU_SMM_SAVE_STATE_LOOKUP_ENTRY > mSmmSmramCpuWidthOffset[] =3D { >=20 > + { 0, 0, 0, 0, = FALSE }, // > Reserved >=20 > + >=20 > + // >=20 > + // Internally defined CPU Save State Registers. Not defined in PI=20 > + SMM CPU > Protocol. >=20 > + // >=20 > + { 4, 4, SMM_CPU_OFFSET (x86.SMMRevId), SMM_CPU_OFFSET > (x64.SMMRevId), 0, FALSE}, = // > SMM_SAVE_STATE_REGISTER_SMMREVID_INDEX =3D 1 >=20 > + >=20 > + // >=20 > + // CPU Save State registers defined in PI SMM CPU Protocol. >=20 > + // >=20 > + { 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 >=20 > + { 0, 8, 0, SMM_CPU_OFFSET (x64._IDTRBaseLo= Dword), > SMM_CPU_OFFSET (x64._IDTRBaseLoDword), FALSE}, // > EFI_SMM_SAVE_STATE_REGISTER_IDTBASE =3D 5 >=20 > + { 0, 8, 0, SMM_CPU_OFFSET (x64._LDTRBaseLo= Dword), > SMM_CPU_OFFSET (x64._LDTRBaseLoDword), FALSE}, // > EFI_SMM_SAVE_STATE_REGISTER_LDTBASE =3D 6 >=20 > + { 0, 2, 0, SMM_CPU_OFFSET (x64._GDTRLimit)= , 0, FALSE}, > // EFI_SMM_SAVE_STATE_REGISTER_GDTLIMIT =3D 7 >=20 > + { 0, 2, 0, SMM_CPU_OFFSET (x64._IDTRLimit)= , 0, FALSE}, > // EFI_SMM_SAVE_STATE_REGISTER_IDTLIMIT =3D 8 >=20 > + { 0, 4, 0, SMM_CPU_OFFSET (x64._LDTRLimit)= , 0, FALSE}, > // EFI_SMM_SAVE_STATE_REGISTER_LDTLIMIT =3D 9 >=20 > + { 0, 0, 0, 0, = 0, FALSE}, // > EFI_SMM_SAVE_STATE_REGISTER_LDTINFO =3D 10 >=20 > + { 4, 2, SMM_CPU_OFFSET (x86._ES), SMM_CPU_OFFSET (x64._ES), > 0, FALSE}, // EFI_SMM_SAVE_STATE_= REGISTER_ES =3D > 20 >=20 > + { 4, 2, SMM_CPU_OFFSET (x86._CS), SMM_CPU_OFFSET (x64._CS), > 0, FALSE}, // EFI_SMM_SAVE_STATE_= REGISTER_CS =3D > 21 >=20 > + { 4, 2, SMM_CPU_OFFSET (x86._SS), SMM_CPU_OFFSET (x64._SS), > 0, FALSE}, // EFI_SMM_SAVE_STATE_= REGISTER_SS =3D > 22 >=20 > + { 4, 2, SMM_CPU_OFFSET (x86._DS), SMM_CPU_OFFSET (x64._DS), > 0, FALSE}, // EFI_SMM_SAVE_STATE_= REGISTER_DS =3D > 23 >=20 > + { 4, 2, SMM_CPU_OFFSET (x86._FS), SMM_CPU_OFFSET (x64._FS), > 0, FALSE}, // EFI_SMM_SAVE_STATE_= REGISTER_FS =3D > 24 >=20 > + { 4, 2, SMM_CPU_OFFSET (x86._GS), SMM_CPU_OFFSET (x64._GS), > 0, FALSE}, // EFI_SMM_SAVE_STATE_= REGISTER_GS =3D > 25 >=20 > + { 0, 2, 0, SMM_CPU_OFFSET (x64._LDTR), = 0, FALSE}, > // EFI_SMM_SAVE_STATE_REGISTER_LDTR_SEL =3D 26 >=20 > + { 0, 2, 0, SMM_CPU_OFFSET (x64._TR), = 0, FALSE}, > // EFI_SMM_SAVE_STATE_REGISTER_TR_SEL =3D 27 >=20 > + { 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 >=20 > + { 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 >=20 > + { 0, 8, 0, SMM_CPU_OFFSET (x64._R8), > SMM_CPU_OFFSET (x64._R8) + 4, TRUE}, // > EFI_SMM_SAVE_STATE_REGISTER_R8 =3D 30 >=20 > + { 0, 8, 0, SMM_CPU_OFFSET (x64._R9), > SMM_CPU_OFFSET (x64._R9) + 4, TRUE}, // > EFI_SMM_SAVE_STATE_REGISTER_R9 =3D 31 >=20 > + { 0, 8, 0, SMM_CPU_OFFSET (x64._R10), > SMM_CPU_OFFSET (x64._R10) + 4, TRUE}, // > EFI_SMM_SAVE_STATE_REGISTER_R10 =3D 32 >=20 > + { 0, 8, 0, SMM_CPU_OFFSET (x64._R11), > SMM_CPU_OFFSET (x64._R11) + 4, TRUE}, // > EFI_SMM_SAVE_STATE_REGISTER_R11 =3D 33 >=20 > + { 0, 8, 0, SMM_CPU_OFFSET (x64._R12), > SMM_CPU_OFFSET (x64._R12) + 4, TRUE}, // > EFI_SMM_SAVE_STATE_REGISTER_R12 =3D 34 >=20 > + { 0, 8, 0, SMM_CPU_OFFSET (x64._R13), > SMM_CPU_OFFSET (x64._R13) + 4, TRUE}, // > EFI_SMM_SAVE_STATE_REGISTER_R13 =3D 35 >=20 > + { 0, 8, 0, SMM_CPU_OFFSET (x64._R14), > SMM_CPU_OFFSET (x64._R14) + 4, TRUE}, // > EFI_SMM_SAVE_STATE_REGISTER_R14 =3D 36 >=20 > + { 0, 8, 0, SMM_CPU_OFFSET (x64._R15), > SMM_CPU_OFFSET (x64._R15) + 4, TRUE}, // > EFI_SMM_SAVE_STATE_REGISTER_R15 =3D 37 >=20 > + { 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 >=20 > + { 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 >=20 > + { 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 >=20 > + { 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 >=20 > + { 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 >=20 > + { 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 >=20 > + { 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 >=20 > + { 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 >=20 > + { 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 >=20 > + >=20 > + { 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 >=20 > + { 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 >=20 > + { 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 >=20 > + { 0, 8, 0, SMM_CPU_OFFSET (x64._CR4), > SMM_CPU_OFFSET (x64._CR4) + 4, FALSE}, // > EFI_SMM_SAVE_STATE_REGISTER_CR4 =3D 54 >=20 > + { 0, 0, 0, 0, = 0 } >=20 > +}; >=20 > + >=20 > +/** >=20 > + Read an SMM Save State register on the target processor. If this=20 > + function >=20 > + returns EFI_UNSUPPORTED, then the caller is responsible for reading=20 > + the >=20 > + SMM Save Sate register. >=20 > + >=20 > + @param[in] CpuIndex The index of the CPU to read the SMM Save=20 > + State. The >=20 > + value must be between 0 and the NumberOfCpus=20 > + field in >=20 > + the System Management System Table (SMST). >=20 > + @param[in] Register The SMM Save State register to read. >=20 > + @param[in] Width The number of bytes to read from the CPU save > state. >=20 > + @param[out] Buffer Upon return, this holds the CPU register value r= ead >=20 > + from the save state. >=20 > + >=20 > + @retval EFI_SUCCESS The register was read from Save State. >=20 > + @retval EFI_INVALID_PARAMTER Buffer is NULL. >=20 > + @retval EFI_UNSUPPORTED This function does not support reading EFI_NOT_FOUND is missed. [Abdul] will make the changes. > Register. >=20 > + >=20 > +**/ >=20 > +EFI_STATUS >=20 > +EFIAPI >=20 > +SmramSaveStateReadRegister ( >=20 > + IN UINTN CpuIndex, >=20 > + IN EFI_SMM_SAVE_STATE_REGISTER Register, >=20 > + IN UINTN Width, >=20 > + OUT VOID *Buffer >=20 > + ) >=20 > +{ >=20 > + UINT32 SmmRevId; >=20 > + EFI_SMM_SAVE_STATE_IO_INFO *IoInfo; >=20 > + AMD_SMRAM_SAVE_STATE_MAP *CpuSaveState; >=20 > + UINT8 DataWidth; >=20 > + >=20 > + // Read CPU State >=20 > + CpuSaveState =3D (AMD_SMRAM_SAVE_STATE_MAP=20 > + *)gSmst->CpuSaveState[CpuIndex]; >=20 > + >=20 > + // Check for special EFI_SMM_SAVE_STATE_REGISTER_LMA >=20 > + if (Register =3D=3D EFI_SMM_SAVE_STATE_REGISTER_LMA) { >=20 > + // Only byte access is supported for this register >=20 > + if (Width !=3D 1) { >=20 > + return EFI_INVALID_PARAMETER; >=20 > + } >=20 > + >=20 > + *(UINT8 *)Buffer =3D SmramSaveStateGetRegisterLma (); >=20 > + >=20 > + return EFI_SUCCESS; >=20 > + } >=20 > + >=20 > + // Check for special EFI_SMM_SAVE_STATE_REGISTER_IO >=20 > + >=20 > + if (Register =3D=3D EFI_SMM_SAVE_STATE_REGISTER_IO) { >=20 > + // >=20 > + // Get SMM Revision ID >=20 > + // >=20 > + SmramSaveStateReadRegisterByIndex (CpuIndex,=20 > + SMM_SAVE_STATE_REGISTER_SMMREVID_INDEX, sizeof (SmmRevId), > &SmmRevId); >=20 > + >=20 > + // >=20 > + // See if the CPU supports the IOMisc register in the save state >=20 > + // >=20 > + if (SmmRevId < AMD_SMM_MIN_REV_ID_X64) { >=20 > + return EFI_NOT_FOUND; >=20 > + } >=20 > + >=20 > + // Check if IO Restart Dword [IO Trap] is valid or not using bit 1. >=20 > + if (!(CpuSaveState->x64.IO_DWord & 0x02u)) { >=20 > + return EFI_NOT_FOUND; >=20 > + } >=20 > + >=20 > + // Zero the IoInfo structure that will be returned in Buffer >=20 > + IoInfo =3D (EFI_SMM_SAVE_STATE_IO_INFO *)Buffer; >=20 > + ZeroMem (IoInfo, sizeof (EFI_SMM_SAVE_STATE_IO_INFO)); >=20 > + >=20 > + IoInfo->IoPort =3D (UINT16)(CpuSaveState->x64.IO_DWord >> 16u); >=20 > + >=20 > + if (CpuSaveState->x64.IO_DWord & 0x10u) { >=20 > + IoInfo->IoWidth =3D EFI_SMM_SAVE_STATE_IO_WIDTH_UINT8; >=20 > + DataWidth =3D 0x01u; >=20 > + } else if (CpuSaveState->x64.IO_DWord & 0x20u) { >=20 > + IoInfo->IoWidth =3D EFI_SMM_SAVE_STATE_IO_WIDTH_UINT16; >=20 > + DataWidth =3D 0x02u; >=20 > + } else { >=20 > + IoInfo->IoWidth =3D EFI_SMM_SAVE_STATE_IO_WIDTH_UINT32; >=20 > + DataWidth =3D 0x04u; >=20 > + } >=20 > + >=20 > + if (CpuSaveState->x64.IO_DWord & 0x01u) { >=20 > + IoInfo->IoType =3D EFI_SMM_SAVE_STATE_IO_TYPE_INPUT; >=20 > + } else { >=20 > + IoInfo->IoType =3D EFI_SMM_SAVE_STATE_IO_TYPE_OUTPUT; >=20 > + } >=20 > + >=20 > + if ((IoInfo->IoType =3D=3D EFI_SMM_SAVE_STATE_IO_TYPE_INPUT) ||=20 > + (IoInfo->IoType =3D=3D EFI_SMM_SAVE_STATE_IO_TYPE_OUTPUT)) { >=20 > + SmramSaveStateReadRegister (CpuIndex,=20 > + EFI_SMM_SAVE_STATE_REGISTER_RAX, DataWidth, &IoInfo->IoData); >=20 > + } >=20 > + >=20 > + return EFI_SUCCESS; >=20 > + } >=20 > + >=20 > + // Convert Register to a register lookup table index >=20 > + return SmramSaveStateReadRegisterByIndex (CpuIndex,=20 > + SmramSaveStateGetRegisterIndex (Register), Width, Buffer); >=20 > +} >=20 > + >=20 > +/** >=20 > + Writes an SMM Save State register on the target processor. If this=20 > + function >=20 > + returns EFI_UNSUPPORTED, then the caller is responsible for writing=20 > + the >=20 > + SMM Save Sate register. >=20 > + >=20 > + @param[in] CpuIndex The index of the CPU to write the SMM Save=20 > + State. The >=20 > + value must be between 0 and the NumberOfCpus=20 > + field in >=20 > + the System Management System Table (SMST). >=20 > + @param[in] Register The SMM Save State register to write. >=20 > + @param[in] Width The number of bytes to write to the CPU save stat= e. >=20 > + @param[in] Buffer Upon entry, this holds the new CPU register value= . >=20 > + >=20 > + @retval EFI_SUCCESS The register was written to Save State. >=20 > + @retval EFI_INVALID_PARAMTER Buffer is NULL. >=20 > + @retval EFI_UNSUPPORTED This function does not support writing EFI_NOT_FOUND is missed. Thanks Abner [Abdul] will make the changes. > Register. >=20 > +**/ >=20 > +EFI_STATUS >=20 > +EFIAPI >=20 > +SmramSaveStateWriteRegister ( >=20 > + IN UINTN CpuIndex, >=20 > + IN EFI_SMM_SAVE_STATE_REGISTER Register, >=20 > + IN UINTN Width, >=20 > + IN CONST VOID *Buffer >=20 > + ) >=20 > +{ >=20 > + UINTN RegisterIndex; >=20 > + AMD_SMRAM_SAVE_STATE_MAP *CpuSaveState; >=20 > + >=20 > + // >=20 > + // Writes to EFI_SMM_SAVE_STATE_REGISTER_LMA are ignored >=20 > + // >=20 > + if (Register =3D=3D EFI_SMM_SAVE_STATE_REGISTER_LMA) { >=20 > + return EFI_SUCCESS; >=20 > + } >=20 > + >=20 > + // >=20 > + // Writes to EFI_SMM_SAVE_STATE_REGISTER_IO are not supported >=20 > + // >=20 > + if (Register =3D=3D EFI_SMM_SAVE_STATE_REGISTER_IO) { >=20 > + return EFI_NOT_FOUND; >=20 > + } >=20 > + >=20 > + // >=20 > + // Convert Register to a register lookup table index >=20 > + // >=20 > + RegisterIndex =3D SmramSaveStateGetRegisterIndex (Register); >=20 > + if (RegisterIndex =3D=3D 0) { >=20 > + return EFI_NOT_FOUND; >=20 > + } >=20 > + >=20 > + CpuSaveState =3D gSmst->CpuSaveState[CpuIndex]; >=20 > + >=20 > + // >=20 > + // Do not write non-writable SaveState, because it will cause exceptio= n. >=20 > + // >=20 > + if (!mSmmSmramCpuWidthOffset[RegisterIndex].Writeable) { >=20 > + return EFI_UNSUPPORTED; >=20 > + } >=20 > + >=20 > + // >=20 > + // Check CPU mode >=20 > + // >=20 > + if (SmramSaveStateGetRegisterLma () =3D=3D > + EFI_SMM_SAVE_STATE_REGISTER_LMA_32BIT) { >=20 > + // >=20 > + // If 32-bit mode width is zero, then the specified register can=20 > + not be accessed >=20 > + // >=20 > + if (mSmmSmramCpuWidthOffset[RegisterIndex].Width32 =3D=3D 0) { >=20 > + return EFI_NOT_FOUND; >=20 > + } >=20 > + >=20 > + // >=20 > + // If Width is bigger than the 32-bit mode width, then the=20 > + specified register can not be accessed >=20 > + // >=20 > + if (Width > mSmmSmramCpuWidthOffset[RegisterIndex].Width32) { >=20 > + return EFI_INVALID_PARAMETER; >=20 > + } >=20 > + >=20 > + // >=20 > + // Write SMM State register >=20 > + // >=20 > + ASSERT (CpuSaveState !=3D NULL); >=20 > + CopyMem ((UINT8 *)CpuSaveState + > + mSmmSmramCpuWidthOffset[RegisterIndex].Offset32, Buffer, Width); >=20 > + } else { >=20 > + // >=20 > + // If 64-bit mode width is zero, then the specified register can=20 > + not be accessed >=20 > + // >=20 > + if (mSmmSmramCpuWidthOffset[RegisterIndex].Width64 =3D=3D 0) { >=20 > + return EFI_NOT_FOUND; >=20 > + } >=20 > + >=20 > + // >=20 > + // If Width is bigger than the 64-bit mode width, then the=20 > + specified register can not be accessed >=20 > + // >=20 > + if (Width > mSmmSmramCpuWidthOffset[RegisterIndex].Width64) { >=20 > + return EFI_INVALID_PARAMETER; >=20 > + } >=20 > + >=20 > + // >=20 > + // Write lower 32-bits of SMM State register >=20 > + // >=20 > + CopyMem ((UINT8 *)CpuSaveState + > + mSmmSmramCpuWidthOffset[RegisterIndex].Offset64Lo, Buffer, MIN (4,=20 > + Width)); >=20 > + if (Width >=3D 4) { >=20 > + // >=20 > + // Write upper 32-bits of SMM State register >=20 > + // >=20 > + CopyMem ((UINT8 *)CpuSaveState +=20 > + mSmmSmramCpuWidthOffset[RegisterIndex].Offset64Hi, (UINT8 *)Buffer > + > + 4, Width - 4); >=20 > + } >=20 > + } >=20 > + >=20 > + return EFI_SUCCESS; >=20 > +} >=20 > + >=20 > +/** >=20 > + Returns LMA value of the Processor. >=20 > + >=20 > + @param[in] VOID >=20 > + >=20 > + @retval UINT8 returns LMA bit value. >=20 > +**/ >=20 > +UINT8 >=20 > +EFIAPI >=20 > +SmramSaveStateGetRegisterLma ( >=20 > + VOID >=20 > + ) >=20 > +{ >=20 > + UINT32 LMAValue; >=20 > + >=20 > + LMAValue =3D (UINT32)AsmReadMsr64 (EFER_ADDRESS) & LMA; >=20 > + if (LMAValue) { >=20 > + return EFI_SMM_SAVE_STATE_REGISTER_LMA_64BIT; >=20 > + } >=20 > + >=20 > + return EFI_SMM_SAVE_STATE_REGISTER_LMA_32BIT; >=20 > +} >=20 > 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 >=20 > + Provides common supporting function to access SMRAM Save State Map >=20 > + >=20 > + Copyright (c) 2010 - 2019, Intel Corporation. All rights=20 > + reserved.
>=20 > + Copyright (C) 2023 Advanced Micro Devices, Inc. All rights=20 > + reserved.
>=20 > + >=20 > + SPDX-License-Identifier: BSD-2-Clause-Patent >=20 > + >=20 > +**/ >=20 > + >=20 > +#include "SmramSaveState.h" >=20 > + >=20 > +extern CONST CPU_SMM_SAVE_STATE_REGISTER_RANGE=20 > +mSmmSmramCpuRegisterRanges[]; >=20 > +extern CONST CPU_SMM_SAVE_STATE_LOOKUP_ENTRY > mSmmSmramCpuWidthOffset[]; >=20 > + >=20 > +/** >=20 > + Read information from the CPU save state. >=20 > + >=20 > + @param Register Specifies the CPU register to read form the save sta= te. >=20 > + >=20 > + @retval 0 Register is not valid >=20 > + @retval >0 Index into mSmmSmramCpuWidthOffset[] associated with=20 > + Register >=20 > + >=20 > +**/ >=20 > +UINTN >=20 > +EFIAPI >=20 > +SmramSaveStateGetRegisterIndex ( >=20 > + IN EFI_SMM_SAVE_STATE_REGISTER Register >=20 > + ) >=20 > +{ >=20 > + UINTN Index; >=20 > + UINTN Offset; >=20 > + >=20 > + for (Index =3D 0, Offset =3D SMM_SAVE_STATE_REGISTER_MAX_INDEX; > + mSmmSmramCpuRegisterRanges[Index].Length !=3D 0; Index++) { >=20 > + if ((Register >=3D mSmmSmramCpuRegisterRanges[Index].Start) &&=20 > + (Register <=3D mSmmSmramCpuRegisterRanges[Index].End)) { >=20 > + return Register - mSmmSmramCpuRegisterRanges[Index].Start +=20 > + Offset; >=20 > + } >=20 > + >=20 > + Offset +=3D mSmmSmramCpuRegisterRanges[Index].Length; >=20 > + } >=20 > + >=20 > + return 0; >=20 > +} >=20 > + >=20 > +/** >=20 > + Read a CPU Save State register on the target processor. >=20 > + >=20 > + This function abstracts the differences that whether the CPU Save=20 > + State register is in the >=20 > + IA32 CPU Save State Map or X64 CPU Save State Map. >=20 > + >=20 > + This function supports reading a CPU Save State register in SMBase > relocation handler. >=20 > + >=20 > + @param[in] CpuIndex Specifies the zero-based index of the CPU s= ave > state. >=20 > + @param[in] RegisterIndex Index into mSmmSmramCpuWidthOffset[] > look up table. >=20 > + @param[in] Width The number of bytes to read from the CPU sa= ve > state. >=20 > + @param[out] Buffer Upon return, this holds the CPU register va= lue > read from the save state. >=20 > + >=20 > + @retval EFI_SUCCESS The register was read from Save State. >=20 > + @retval EFI_NOT_FOUND The register is not defined for the Save > State of Processor. >=20 > + @retval EFI_INVALID_PARAMTER This or Buffer is NULL. >=20 > + >=20 > +**/ >=20 > +EFI_STATUS >=20 > +EFIAPI >=20 > +SmramSaveStateReadRegisterByIndex ( >=20 > + IN UINTN CpuIndex, >=20 > + IN UINTN RegisterIndex, >=20 > + IN UINTN Width, >=20 > + OUT VOID *Buffer >=20 > + ) >=20 > +{ >=20 > + if (RegisterIndex =3D=3D 0) { >=20 > + return EFI_NOT_FOUND; >=20 > + } >=20 > + >=20 > + if (SmramSaveStateGetRegisterLma () =3D=3D > + EFI_SMM_SAVE_STATE_REGISTER_LMA_32BIT) { >=20 > + // >=20 > + // If 32-bit mode width is zero, then the specified register can=20 > + not be accessed >=20 > + // >=20 > + if (mSmmSmramCpuWidthOffset[RegisterIndex].Width32 =3D=3D 0) { >=20 > + return EFI_NOT_FOUND; >=20 > + } >=20 > + >=20 > + // >=20 > + // If Width is bigger than the 32-bit mode width, then the=20 > + specified register can not be accessed >=20 > + // >=20 > + if (Width > mSmmSmramCpuWidthOffset[RegisterIndex].Width32) { >=20 > + return EFI_INVALID_PARAMETER; >=20 > + } >=20 > + >=20 > + // >=20 > + // Write return buffer >=20 > + // >=20 > + ASSERT (gSmst->CpuSaveState[CpuIndex] !=3D NULL); >=20 > + CopyMem (Buffer, (UINT8 *)gSmst->CpuSaveState[CpuIndex] +=20 > + mSmmSmramCpuWidthOffset[RegisterIndex].Offset32, Width); >=20 > + } else { >=20 > + // >=20 > + // If 64-bit mode width is zero, then the specified register can=20 > + not be accessed >=20 > + // >=20 > + if (mSmmSmramCpuWidthOffset[RegisterIndex].Width64 =3D=3D 0) { >=20 > + return EFI_NOT_FOUND; >=20 > + } >=20 > + >=20 > + // >=20 > + // If Width is bigger than the 64-bit mode width, then the=20 > + specified register can not be accessed >=20 > + // >=20 > + if (Width > mSmmSmramCpuWidthOffset[RegisterIndex].Width64) { >=20 > + return EFI_INVALID_PARAMETER; >=20 > + } >=20 > + >=20 > + // >=20 > + // Write lower 32-bits of return buffer >=20 > + // >=20 > + CopyMem (Buffer, (UINT8 *)gSmst->CpuSaveState[CpuIndex] +=20 > + mSmmSmramCpuWidthOffset[RegisterIndex].Offset64Lo, MIN (4, Width)); >=20 > + if (Width >=3D 4) { >=20 > + // >=20 > + // Write upper 32-bits of return buffer >=20 > + // >=20 > + CopyMem ((UINT8 *)Buffer + 4, (UINT8=20 > + *)gSmst->CpuSaveState[CpuIndex] +=20 > + mSmmSmramCpuWidthOffset[RegisterIndex].Offset64Hi, Width - 4); >=20 > + } >=20 > + } >=20 > + >=20 > + return EFI_SUCCESS; >=20 > +} >=20 > -- > 2.25.1 >=20 >=20 >=20 >=20 >=20