From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from NAM11-DM6-obe.outbound.protection.outlook.com (NAM11-DM6-obe.outbound.protection.outlook.com [40.107.223.83]) by mx.groups.io with SMTP id smtpd.web10.134349.1673757913890164651 for ; Sat, 14 Jan 2023 20:45:14 -0800 Authentication-Results: mx.groups.io; dkim=pass header.i=@amd.com header.s=selector1 header.b=r/gTNwUf; 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.223.83, mailfrom: abner.chang@amd.com) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=IkhLAMEc3dzPAmW65RMSYT+yF2Mt3rzt24TYGnEnTMhkJ41YdX8Pt4Zz+sgz/mRko1CjRNjtyCqs+FtdoZgl3ss5UcqjeNaSfoB19m8pPZ80FhDO60r1/Sqma0x812FHCO4I0qw0LNkFZSt9LuyX7p5AJRn8GY+JenwbDdBy2AjiiOTvd509xodTNaiZJfUXxJ9D6zCZIZFY1hDYP1ae8rIdYKbT/y8/cLyotXGWSVrOf3dbmqYvjmOZWte5sYa2KCa20v1aEVfU4iNi4E9bGDyX/eLQ9qbd8XbJ2mGSqMjzkNRoTMq01ctK1AqMs18ehemIxuKo3YFyGnnIpVT/PQ== 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=sgpZXi144dMK6aQpgC7v7PRK6jKKfRX2QSXKYrK06kI=; b=JstI6XtnfldeLn0qUNZZnGI5Q/t74DIXHdcofS+paJc2QDYj+K850g3rN5KfZkdAd4X5tyX8bo8+rkjUAK59+ZX3Q+q4hPzfI9QhtIRNgF1Kvun43dI6LXeYPkP70rs2r3ySPZkAFCtUMt1cQ9jTagL7WCZu8+SnbkI4Yos9cBQgP/ymDJnv9/8lTFGU7VsYeojVVHoHJgiZn6fVITsNDLie7lkdQmUN6XFobdJdW2qTG9ZgGAhcHZynenCrQAA//qila3W1TaJ51PFSQwDQKtTXQOCCCWk8+FxRouE4e32b2lJIa6RCA9PFHZGqgAnINRn27rft+P/L4VRyT+a+dw== 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=sgpZXi144dMK6aQpgC7v7PRK6jKKfRX2QSXKYrK06kI=; b=r/gTNwUfImTYEN3AeZPca7WzUV7QAso5hr43dkZNpwobCsmwY3SjRExP8w1a1bM5uF/0JDTnZMF1eLoCJdvV05JThWzysySzqTwbEqNPoC6mEQIlao33Ck8kjXf6fs4Veq3bCY1zGgSckxu1zHu8jdPDfWB0DCejuBbgEMAcB+E= Received: from MN2PR12MB3966.namprd12.prod.outlook.com (2603:10b6:208:165::18) by MN2PR12MB4240.namprd12.prod.outlook.com (2603:10b6:208:1d3::14) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5986.19; Sun, 15 Jan 2023 04:45:11 +0000 Received: from MN2PR12MB3966.namprd12.prod.outlook.com ([fe80::cddb:3de9:cd1d:26e4]) by MN2PR12MB3966.namprd12.prod.outlook.com ([fe80::cddb:3de9:cd1d:26e4%5]) with mapi id 15.20.5986.022; Sun, 15 Jan 2023 04:45:10 +0000 From: "Chang, Abner" 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 SmmSmramSaveStateLib library class Thread-Topic: [edk2-devel] [PATCH v2 4/6] UefiCpuPkg: Implements SmmSmramSaveStateLib library class Thread-Index: AQHZJYRh6BtUuIJ0FEK3Ih0VYGB94a6eFUBA Date: Sun, 15 Jan 2023 04:45:10 +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-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: MN2PR12MB3966:EE_|MN2PR12MB4240:EE_ x-ms-office365-filtering-correlation-id: fdfdcb48-3783-409a-6794-08daf6b348b5 x-ms-exchange-senderadcheck: 1 x-ms-exchange-antispam-relay: 0 x-microsoft-antispam: BCL:0; x-microsoft-antispam-message-info: RT9d26cp6bDVuOc1YMG5c1+ruo6jQpi0jt1MLawG3TiD0HSfi/kIapfEKm5+fpwiu4IiX9E/dex2uVAjSQdE7Z3BqGz8Y9Eueh/m1gGZh1/rWTbObhxVJn4c1n+MjYzhqMGgPI0v/Y4I3IwGk9/Vta/Yt6H/V+eoT2QlyQO1Hn+ef86ZwPppD+XZYdIeeYP/PzymWGlupufbvt1QGoUbn3k1Z8AXOg4yxUjUDXoVsjYql8jxH9Q01gfmIO527P1ve3ERB7l1P061qpziAZLKfITgsV6fJUc47/D46zpcc7w044Gw9RVHnJ4gzRsswnIcVoFAUtEDNqbnSOg5qkH5NlVGAGuHLc3K3lqOxNxaqnpeYfAR91kKMYjlgUgNIZBWkfJ5n5kEm2/YondgKAEvFNF9rpiLEM9UNvqQCrX9NLXgwIy7QuKCQorWm+ED3AQGzOG9RCNo8uETKfY5Os/2y5Hc8WxEK7NvVXLDKVue7FMSqlUpaiBHGjSP9DZRwQwx4WsQRbbiToYNrpzBErghybj0YEO9WXMjW0QfYWFNW9gbyrtxv0VE5uVGs5tE8wxIFDIBANYaXzqDPQqgB6VggrineXgZr8gh+qR7w+SJdL258KGJoAMPBEpkctqOqOiRQEbhyHrwOccx3eHyRMESLJuORM9al0KlwJIUx6WsDWm70Qa1UeAzCjkaYj/Bwz9ynyDNhhwB4rhJHXlIMirDmZEiH5cCyQvKzfYS1mYEMBOn7BcJmxKTbS0fVQuaWwow 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)(396003)(376002)(346002)(366004)(136003)(39860400002)(451199015)(41300700001)(186003)(9686003)(5660300002)(8936002)(33656002)(52536014)(30864003)(53546011)(26005)(71200400001)(966005)(76116006)(38100700002)(478600001)(6506007)(83380400001)(54906003)(110136005)(6636002)(316002)(38070700005)(4326008)(64756008)(86362001)(66446008)(66476007)(66556008)(66946007)(55016003)(8676002)(122000001)(7696005)(45080400002)(66899015)(2906002)(213903007)(559001)(579004);DIR:OUT;SFP:1101; x-ms-exchange-antispam-messagedata-chunkcount: 1 x-ms-exchange-antispam-messagedata-0: =?us-ascii?Q?LMIrIXg0xa/9ZN+wwMPyLw/dTaXMNbNGh/qLcPKsmRrOzU52G9bl+871f7vL?= =?us-ascii?Q?w3V8aNB5dKNU6iqR3MD7PRoDz4FgaFozn6SrgE/jpROrp9VlsJZSB6dKkJAL?= =?us-ascii?Q?AZAuKPFdWTeK/nMCsyx6l5PB32pp87k0NgyJtibSJIcH2YiIF7b4d9t88lU7?= =?us-ascii?Q?K/98ana8w4JCzttEauCmfQRI4oJr5WQ6KyjmyGc8xvA27be+l9jY1HRnKjLj?= =?us-ascii?Q?D8/d/Dd+vEHtoodbh8aiU59687CR8SSa9ybfVdIWF40vFaimXAAmrGfAwzz/?= =?us-ascii?Q?QpnNgMUmU7zJOXeyiF116JsQptJPx/MYjANyF11Gv7KzZ+p/x9LnpQ55K3ci?= =?us-ascii?Q?z35/RIJOVlVUhwEyFcytpCpQUmeGEN5lo2ZBypK4V/YiAfTB0l8FIKrWJyq6?= =?us-ascii?Q?u33HEdsWEyBxq1ZS2THH7nqMv3hOVfc/WYUCMvo+sJPepnaHf3Bn2HMaHa1l?= =?us-ascii?Q?HiY1dqxA6/oKxe03svISAn50XLCpG7DKvQxzBxbfNCWqmvp6XIVn8TgDCI9z?= =?us-ascii?Q?KMyzEEP/uCxt2+7vIf8qnYfQtq1O0jaRmr8TWjtBTLjFSeCx47eMHkxanLEn?= =?us-ascii?Q?NnIbSGg4/POTlpELk3HqANmrS1wJETWcGaqcHUmvOML0h1/JqzXMf8uLI2D9?= =?us-ascii?Q?JpanDY3FdJiYNinIBHy9mNT0OXV2Wsc5LU+2wcc1RwPp4CI/SdI6h9clrC72?= =?us-ascii?Q?ZNBH/0CTNgoGrTYb/Y46ZldeEyU8dAdbhCkPSV86eS6QdMLPK3wiK5hl8ul2?= =?us-ascii?Q?jmE3s9owqCYKDERgzhGywfmm89q8sehzwNrd1jOeOmrC60m0zL8+kaXmoxY2?= =?us-ascii?Q?yVO9dnbQ1w2padadwAGZczfEg3K33vTM3qODXZlL6biXFygPl2V5DJv0KXOJ?= =?us-ascii?Q?yzYzMmMSVrFv2EcOnyWTMue2tx1SodQTqeVDasiq7drx0asRIjuAsVRa6h7r?= =?us-ascii?Q?P0KtUp/FUGR5H2q6limyPxorxkcYQQjrlAlSdeZ71E/vCIQG7dD8Im7Du2Gz?= =?us-ascii?Q?JDSNVSdPxwwSTzaDuf1v4nZs43EpDGRQX5iIgZ+v76qPDWEiomAPqolH4QoI?= =?us-ascii?Q?YO7bG4QQOKIK5Z5mbflx8NHy5LhiVT6oJfD6+Mn6lVMhl14dFRj9pX/B+My9?= =?us-ascii?Q?1qQMLjFpFRVTEU1NCZgMZmbAF2n5OKXinnwJl/pMDIBz+lbXt6euduWWXc6a?= =?us-ascii?Q?brMgTQH9vBXSyisHmTbdQaMQP/tG4v5JQSkoJ3a3eBw6LjarvNhtP6LFLmVC?= =?us-ascii?Q?i75WSoVRuPyY2q9Li8EwQVRvQddYPdNU8V3rrn5X1o8DmoH5s3sTGQvXyWBz?= =?us-ascii?Q?PQMaosZXSE6oAuD6xrEDS8hbqW0nmbwMGmiPnM66Nw4S+cm8syf8QAfVKyZe?= =?us-ascii?Q?lcTl0KjoLYk31OP3cOitnbQ5+60R+Lj3MDMGyK/hBgmRKEB1UcHxsdZaimJK?= =?us-ascii?Q?ct9m3d/+qB6g/9A+o+Qhr/rIopAKf67zGoZnDWLIyUsqH98IwjmXbuHPYswu?= =?us-ascii?Q?EaJ+6i9D1SIsNKNel7kUtxLDSyHOxaolRia3a09w1Omhh7d5ZLgDEgFh5bDi?= =?us-ascii?Q?mW3eE+MAwMUB7jIfVPj/Zuxk9yR9TLAl4dUQU9xa?= 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: fdfdcb48-3783-409a-6794-08daf6b348b5 X-MS-Exchange-CrossTenant-originalarrivaltime: 15 Jan 2023 04:45:10.5460 (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: xQOsA8YS4FVl5t7BWn6E6NZlcP0fWwZUWWbOmPShCei1YQps4zQidB0g8VcD009l1aM1kFPgb7Z8Yhbrn3VUNg== X-MS-Exchange-Transport-CrossTenantHeadersStamped: MN2PR12MB4240 Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable [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 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. Other comments in below,=20 > -----Original Message----- > From: devel@edk2.groups.io On Behalf Of Abdul > Lateef Attar via groups.io > Sent: Wednesday, January 11, 2023 2:16 PM > 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: [edk2-devel] [PATCH v2 4/6] UefiCpuPkg: Implements > SmmSmramSaveStateLib library class >=20 > Caution: This message originated from an External Source. Use proper > 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 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 reserved. >=20 > +# Copyright (C) 2023 Advanced Micro Devices, Inc. All rights > +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 read > +and >=20 > +# save savestate area registers. >=20 > +# >=20 > +# Copyright (C) 2023 Advanced Micro Devices, Inc. All rights > +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 > + reserved.
>=20 > + Copyright (C) 2023 Advanced Micro Devices, Inc. All rights > + 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 > +CPU_SMM_SAVE_STATE_REGISTER_RANGE >=20 > +#define SMM_REGISTER_RANGE(Start, End) { Start, End, End - Start + 1 } >=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 > +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 > + 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 > + 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 reserved.
>=20 > +Copyright (C) 2023 Advanced Micro Devices, Inc. All rights > +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 > +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 > +EFI_SMM_SAVE_STATE_REGISTER >=20 > +// value to an index into a table of type > +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 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 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 > + function >=20 > + returns EFI_UNSUPPORTED, then the caller is responsible for reading > + the >=20 > + SMM Save Sate register. >=20 > + >=20 > + @param[in] CpuIndex The index of the CPU to read the SMM Save > + State. The >=20 > + value must be between 0 and the NumberOfCpus > + 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. > 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 > + *)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, > + 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) || > + (IoInfo->IoType =3D=3D EFI_SMM_SAVE_STATE_IO_TYPE_OUTPUT)) { >=20 > + SmramSaveStateReadRegister (CpuIndex, > + 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, > + SmramSaveStateGetRegisterIndex (Register), Width, Buffer); >=20 > +} >=20 > + >=20 > +/** >=20 > + Writes an SMM Save State register on the target processor. If this > + function >=20 > + returns EFI_UNSUPPORTED, then the caller is responsible for writing > + the >=20 > + SMM Save Sate register. >=20 > + >=20 > + @param[in] CpuIndex The index of the CPU to write the SMM Save > + State. The >=20 > + value must be between 0 and the NumberOfCpus > + 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 > 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 > + 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 > + 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 > + 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 > + 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, > + Width)); >=20 > + if (Width >=3D 4) { >=20 > + // >=20 > + // Write upper 32-bits of SMM State register >=20 > + // >=20 > + CopyMem ((UINT8 *)CpuSaveState + > + 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 > + reserved.
>=20 > + Copyright (C) 2023 Advanced Micro Devices, Inc. All rights > + 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 > +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 > + 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) && > + (Register <=3D mSmmSmramCpuRegisterRanges[Index].End)) { >=20 > + return Register - mSmmSmramCpuRegisterRanges[Index].Start + > + 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 > + 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 > + 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 > + 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] + > + mSmmSmramCpuWidthOffset[RegisterIndex].Offset32, Width); >=20 > + } else { >=20 > + // >=20 > + // If 64-bit mode width is zero, then the specified register can > + 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 > + 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] + > + 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 > + *)gSmst->CpuSaveState[CpuIndex] + > + mSmmSmramCpuWidthOffset[RegisterIndex].Offset64Hi, Width - 4); >=20 > + } >=20 > + } >=20 > + >=20 > + return EFI_SUCCESS; >=20 > +} >=20 > -- > 2.25.1 >=20 >=20 >=20 >=20 >=20