From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by spool.mail.gandi.net (Postfix) with ESMTPS id 0158F74003D for ; Tue, 19 Dec 2023 10:11:32 +0000 (UTC) DKIM-Signature: a=rsa-sha256; bh=RbzeQf7DLCj2EpuOnodwuI5dzVFxvmLEIFfpIGIx1o4=; c=relaxed/simple; d=groups.io; h=ARC-Seal:ARC-Message-Signature:ARC-Authentication-Results:From:To:CC:Subject:Thread-Topic:Thread-Index:Date:Message-ID:References:In-Reply-To:Accept-Language:MIME-Version:Precedence:List-Subscribe:List-Help:Sender:List-Id:Mailing-List:Delivered-To:Reply-To:List-Unsubscribe-Post:List-Unsubscribe:Content-Language:Content-Type:Content-Transfer-Encoding; s=20140610; t=1702980691; v=1; b=BpMDlsfY+N28147jXblK/L22TIe9/95fzIJ0zxY2ZT/PBSa047Ds9H9/FAxrsKgrPYMHgJ+F CrdZe30nzatda5FNk328regojjMfjMjxW9b2eGI7xtqINUFGL421/OimxNWSXio9uGF8GEBHpKr M0de+YAKB+Bf5fJK7rqqpaSM= X-Received: by 127.0.0.2 with SMTP id ebDUYY7687511xUl2kBlzJQM; Tue, 19 Dec 2023 02:11:31 -0800 X-Received: from mgamail.intel.com (mgamail.intel.com [134.134.136.24]) by mx.groups.io with SMTP id smtpd.web11.9117.1702980690363212266 for ; Tue, 19 Dec 2023 02:11:30 -0800 X-IronPort-AV: E=McAfee;i="6600,9927,10928"; a="398421517" X-IronPort-AV: E=Sophos;i="6.04,287,1695711600"; d="scan'208";a="398421517" X-Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by orsmga102.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 19 Dec 2023 02:11:29 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10928"; a="894231490" X-IronPort-AV: E=Sophos;i="6.04,287,1695711600"; d="scan'208";a="894231490" X-Received: from orsmsx602.amr.corp.intel.com ([10.22.229.15]) by fmsmga002.fm.intel.com with ESMTP/TLS/AES256-GCM-SHA384; 19 Dec 2023 02:11:29 -0800 X-Received: from orsmsx612.amr.corp.intel.com (10.22.229.25) by ORSMSX602.amr.corp.intel.com (10.22.229.15) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.35; Tue, 19 Dec 2023 02:11:28 -0800 X-Received: from orsmsx610.amr.corp.intel.com (10.22.229.23) by ORSMSX612.amr.corp.intel.com (10.22.229.25) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.35; Tue, 19 Dec 2023 02:11:27 -0800 X-Received: from ORSEDG602.ED.cps.intel.com (10.7.248.7) by orsmsx610.amr.corp.intel.com (10.22.229.23) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.35 via Frontend Transport; Tue, 19 Dec 2023 02:11:27 -0800 X-Received: from NAM02-BN1-obe.outbound.protection.outlook.com (104.47.51.40) by edgegateway.intel.com (134.134.137.103) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.1.2507.35; Tue, 19 Dec 2023 02:11:26 -0800 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=FH6PFC2vxjr59bPiMIB+A61jF50WHjCCoquMDoO3zkrnI3qpASGwI/4pZaRovZJDRCKm1f4Fjr2y03vnZhlMDYpbL7rOG/Kj/0svKKdmIWo6tyzSOYowzjvXowZPjAysW3FJbCTouet5IjJ3EwmV1YZteNzig2rkKKuGPlzOJlgRhDuA4ZI2QUDRdKLgJzy7wRaWWexTLFr5ZdxhaH2uqime81Spk6wjRz77iwOc5Z10yrLxaFkWc6PxY0NDEScl/D67KmwXMZurrBF9v3qw50nmP9tVSm0z6vhXT7lUDakLnWa8snapv48gh1vKWE9CUN0CYGZcel7bV6rLRmdJJw== 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=zFsX8sGvUjz+tlLjQxHeavOloVNQIJdsCVQPcMBAxLg=; b=RzDX+/k25tmsISGGmxZuvyjgy+mh37XFaoH19dUqbgje2xKyyvml924RBstU0ogBb/Aej/mzBGMd8rqMVUP+m2EGVxTz0H6MCiIsvZjEKTBtJsl+wI0EE4ZVvwiXGSChC7a7lJu3HxKxYBB6Ojl4BT0ne6IBq6uvEGYoIsAxPpcyU+6Gw2XyEfeebaeo5tZE7mC8IVbJlhdmu7NdXFn05h/iX/UF8tYw87rdaTOI3I8p267wzsVDoM4oBHsbridWl5bG4KVIJ+qJLY9GoLpk7lLHrRN5vvBgNi74I/vL6AexNOt2hRv1XBEOw6gkt3hQETC/QuAMIlF5AT31PT5lhg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=intel.com; dmarc=pass action=none header.from=intel.com; dkim=pass header.d=intel.com; arc=none X-Received: from MN0PR11MB6158.namprd11.prod.outlook.com (2603:10b6:208:3ca::18) by PH7PR11MB8123.namprd11.prod.outlook.com (2603:10b6:510:236::5) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7091.38; Tue, 19 Dec 2023 10:11:23 +0000 X-Received: from MN0PR11MB6158.namprd11.prod.outlook.com ([fe80::864d:d91a:4674:e0f7]) by MN0PR11MB6158.namprd11.prod.outlook.com ([fe80::864d:d91a:4674:e0f7%7]) with mapi id 15.20.7091.034; Tue, 19 Dec 2023 10:11:23 +0000 From: "Wu, Jiaxin" To: "Ni, Ray" , "devel@edk2.groups.io" CC: Laszlo Ersek , "Dong, Eric" , "Zeng, Star" , Gerd Hoffmann , "Kumar, Rahul R" Subject: Re: [edk2-devel] [PATCH v5 4/8] UefiCpuPkg: Implements SmmCpuSyncLib library instance Thread-Topic: [PATCH v5 4/8] UefiCpuPkg: Implements SmmCpuSyncLib library instance Thread-Index: AQHaMkuiaUiBr0r1MEusjioEof0DmLCwWEqwgAAJt7A= Date: Tue, 19 Dec 2023 10:11:23 +0000 Message-ID: References: <20231219071839.4248-1-jiaxin.wu@intel.com> <20231219071839.4248-5-jiaxin.wu@intel.com> In-Reply-To: Accept-Language: zh-CN, en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-ms-publictraffictype: Email x-ms-traffictypediagnostic: MN0PR11MB6158:EE_|PH7PR11MB8123:EE_ x-ms-office365-filtering-correlation-id: 2876e828-2086-49c7-172b-08dc007ada9b x-ms-exchange-senderadcheck: 1 x-ms-exchange-antispam-relay: 0 x-microsoft-antispam-message-info: EAl9AuHhYvjNyLQB5HzvlkL5iFFLdXXV3HkdXWKuGTiJq0ChzLuHdSoFPZylHOGtCo87daGE5sCjURfFxIGCEyuP7tUbjrVvt1GU0TlEZk0CzhdNgx9Mp33W+Vvaa0MhvP4i7u+e+59yCMahUjhBrYyBbDEzKONujJPhVAm9BleCHOINTFuibhtkIiQ4mlzxbJ5F3XTDrkIo0r+99j571aoOMok8NA9s/9KQONC0tpHW/b9zsqItP0f+PYzs1SbLeNKUU75fztb/fA7++9a8jVXjfXMBGEo1vcX/Ur5b0Te9cNrkcdylJC5GuCPI5i3JaldvODEl7No26SAcwpbz/2JgligQiR92W61M4uaFpcOaBKC7DSqqQ8UpzYQpe8wOyrRM8UgEY8Wm2GIX8IEkOaTHh51nJCaccS2yRlNWK5k3xKVA2+P1jimfx6Z0pXWGSijUbRPh69odPCb99ptpDVx9xeTmtZepJsJmbZ+ARQMHT8RRCuXR/ozQetEaVQ3H7lNTjhLVFtU91k3c3QuD0qPAq0RQa7t/45/m5pJIGlnXmaFLxjjjKbS7PvaORL8ZTZ0kT2dgGEbLUD1Ur1Psx+8Ekhmq5k2erjDR351KmgE= x-ms-exchange-antispam-messagedata-chunkcount: 1 x-ms-exchange-antispam-messagedata-0: =?us-ascii?Q?aN+TS7uFnVP0jkLCBXwlFGeYnVb4Z+5nVuZ0tFbcY50bgOzU+F3RbgFSvhv2?= =?us-ascii?Q?QLOykPFwYqEq1Hkptykx9LnvgNopUJuFQP+/XvFOp9aayBCfIQjfOf9Pwmwp?= =?us-ascii?Q?VL0smPG1DEXw2QyfOVp2D2II9/hIljzTREPD+YcQ06qBzohuW6FD0odWWIMp?= =?us-ascii?Q?YY1YZ8xEuTFDJBELAjU2h1oPwm90pTHN3ty2OujKie3FGMHPKp4+XjOgng95?= =?us-ascii?Q?VNvsWUQoTAOg9UuqoZokU1aw9X1PcaxaotYxLtG32iqfFoYCFIevj/+vxih5?= =?us-ascii?Q?4SQdLUNCTcsPt/UXV1z3LvnkkSvmg1nrLYP8WgMfjVO/6QpnWMRdoX23SWMR?= =?us-ascii?Q?wtwynVpltrAuW6eCPnDwFkvbqJ8nTikHU/IbvtNSIkEX6q7edLD4f49LKszF?= =?us-ascii?Q?DdOgf70SWDAhOzRUUIGfFgdn6FEMNVTU4fZZQCvTMhTsJ6vwHUdUA03yl9ru?= =?us-ascii?Q?mCowtZ/BGNRzZAL0okWWQQEMA/Dp7aCvIsIYAkUs9IPF32JmkRICD0obc5RQ?= =?us-ascii?Q?fGgo79pxBGV5HRz2cEHPWOkHzPtx40S140iRn2hxSxSN8L+JnuGZdeU//7hf?= =?us-ascii?Q?U4+b6FoyX+hB+zU3aI3kUJO6QxwCYEQWBKrJxRb0j5hzNNFFNluYW6qhR2J8?= =?us-ascii?Q?8EPxn9LSI2JTnjaTk6pyjRrUFAgTPkNe6srvV6l0Ga7WB58YcVwskc/3Bdxa?= =?us-ascii?Q?uqR4VDMVKlvsakB2hB8qyrNUvFC2JgxF5MzjECukBuIo4zieegdqJZQO+goU?= =?us-ascii?Q?1uiGtIKHcKcOn26X3gCDdp3f1ZKL0jN0ZULnBL9AQJg+8VaZsCIKoANnD8tT?= =?us-ascii?Q?r9xAz8GSitTJs0Njf5nK5BYUTUT/RHWBD/kRGql3S9v/46GvhLvNTmoz5cCT?= =?us-ascii?Q?AEXfwukud7QD5MT8xEegl07+DESUIkeVZychE7ug1Su4z9gl81q4AuzwQTV8?= =?us-ascii?Q?QMV3Itlvau5246iK8ZchIL8vmNy87l/pQ0zJKN7wcMsz+7zczElzv1uRYirY?= =?us-ascii?Q?ZqvTb8EGtRF5b+1R3BqPWa2o2vr1FJCpuLthoyvPDmSDDOgIaaBGwr3J0PmX?= =?us-ascii?Q?ca+j94CHqzzruYJAia8yGa/5gdpFu4LNq3Cd1GCa9WOnV4lMr0ZqT2Ufe3LN?= =?us-ascii?Q?j5rNWvIfWawV9YWuY0/JSSYMLHIYRRtIU8EVTYdqmEDceyL2I2O3Ur3Smbmo?= =?us-ascii?Q?y35t2i5+CD1yNpRpt/UBPJyh2+NTUUfzQb9HRapCX8OTrqh6sGwZxufKVdyJ?= =?us-ascii?Q?3v/BX9/0Qk6ocYIEStgX8rXlI23eyLGljDmwSlkztgGlLOgLkrjHjlMG30BB?= =?us-ascii?Q?t+5uu+K7m78t+1l1K/rMNcyjFX38/Zbj9DBhpgCHX8iMA9P6Vfy43Zuq2pPU?= =?us-ascii?Q?NtX7cRxmULIst9vCFaE7x+FOZfO3QjVRQsPtbm4u377Pln6ayyiza45upFkq?= =?us-ascii?Q?MzyN8VUOVFq83mdKZKlZ0rPkQ4jvsJ/q7gHFXR4N5qe/b7PSofrRowMlZyp7?= =?us-ascii?Q?XKSDt+KmlFvstsNmAbUW3gYfgpZL5sCQtlgbuSokyknHlkDkZEDzXmizQRB7?= =?us-ascii?Q?sLuopK5KNuuY3girT2F4ewPgW6iLduk2KTNY8h9j?= MIME-Version: 1.0 X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-AuthSource: MN0PR11MB6158.namprd11.prod.outlook.com X-MS-Exchange-CrossTenant-Network-Message-Id: 2876e828-2086-49c7-172b-08dc007ada9b X-MS-Exchange-CrossTenant-originalarrivaltime: 19 Dec 2023 10:11:23.2846 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: 46c98d88-e344-4ed4-8496-4ed7712e255d X-MS-Exchange-CrossTenant-mailboxtype: HOSTED X-MS-Exchange-CrossTenant-userprincipalname: NAB8hluQ3Z/yBekBsvucHWAZrmQIQwSSvEDaXqH8KSiaxT9yPwKGhH9m3FYi6RjfsmQabaC8PP/h0q68PZbPuw== X-MS-Exchange-Transport-CrossTenantHeadersStamped: PH7PR11MB8123 X-OriginatorOrg: intel.com Precedence: Bulk List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,jiaxin.wu@intel.com List-Unsubscribe-Post: List-Unsubscribe=One-Click List-Unsubscribe: X-Gm-Message-State: 490P6XryFhohRkGUvy762Ax2x7686176AA= Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable X-GND-Status: LEGIT Authentication-Results: spool.mail.gandi.net; dkim=pass header.d=groups.io header.s=20140610 header.b=BpMDlsfY; dmarc=fail reason="SPF not aligned (relaxed), DKIM not aligned (relaxed)" header.from=intel.com (policy=none); spf=pass (spool.mail.gandi.net: domain of bounce@groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce@groups.io; arc=reject ("signature check failed: fail, {[1] = sig:microsoft.com:reject}") Thanks all help review this series patches, I have created one PR integrate= d all reviewed by tag for this series patches. https://github.com/tianocore/edk2/pull/5092 Thanks, Jiaxin > -----Original Message----- > From: Ni, Ray > Sent: Tuesday, December 19, 2023 5:34 PM > To: Wu, Jiaxin ; devel@edk2.groups.io > Cc: Laszlo Ersek ; Dong, Eric ; > Zeng, Star ; Gerd Hoffmann ; > Kumar, Rahul R > Subject: RE: [PATCH v5 4/8] UefiCpuPkg: Implements SmmCpuSyncLib library > instance >=20 > Reviewed-by: Ray Ni >=20 > Thanks, > Ray > > -----Original Message----- > > From: Wu, Jiaxin > > Sent: Tuesday, December 19, 2023 3:19 PM > > To: devel@edk2.groups.io > > Cc: Laszlo Ersek ; Dong, Eric ;= Ni, > > Ray ; Zeng, Star ; Gerd Hoffmann > > ; Kumar, Rahul R > > Subject: [PATCH v5 4/8] UefiCpuPkg: Implements SmmCpuSyncLib library > > instance > > > > Implements SmmCpuSyncLib Library instance. The instance refers the > > existing SMM CPU driver (PiSmmCpuDxeSmm) sync implementation > > and behavior: > > 1.Abstract Counter and Run semaphores into SmmCpuSyncCtx. > > 2.Abstract CPU arrival count operation to > > SmmCpuSyncGetArrivedCpuCount(), SmmCpuSyncCheckInCpu(), > > SmmCpuSyncCheckOutCpu(), SmmCpuSyncLockDoor(). > > Implementation is aligned with existing SMM CPU driver. > > 3. Abstract SMM CPU Sync flow to: > > BSP: SmmCpuSyncReleaseOneAp --> AP: SmmCpuSyncWaitForBsp > > BSP: SmmCpuSyncWaitForAPs <-- AP: SmmCpuSyncReleaseBsp > > Semaphores release & wait during sync flow is same as existing SMM > > CPU driver. > > 4.Same operation to Counter and Run semaphores by leverage the atomic > > compare exchange. > > > > Cc: Laszlo Ersek > > Cc: Eric Dong > > Cc: Ray Ni > > Cc: Zeng Star > > Cc: Gerd Hoffmann > > Cc: Rahul Kumar > > Signed-off-by: Jiaxin Wu > > --- > > UefiCpuPkg/Library/SmmCpuSyncLib/SmmCpuSyncLib.c | 652 > > +++++++++++++++++++++ > > UefiCpuPkg/Library/SmmCpuSyncLib/SmmCpuSyncLib.inf | 34 ++ > > UefiCpuPkg/UefiCpuPkg.dsc | 2 + > > 3 files changed, 688 insertions(+) > > create mode 100644 > > UefiCpuPkg/Library/SmmCpuSyncLib/SmmCpuSyncLib.c > > create mode 100644 > > UefiCpuPkg/Library/SmmCpuSyncLib/SmmCpuSyncLib.inf > > > > diff --git a/UefiCpuPkg/Library/SmmCpuSyncLib/SmmCpuSyncLib.c > > b/UefiCpuPkg/Library/SmmCpuSyncLib/SmmCpuSyncLib.c > > new file mode 100644 > > index 0000000000..d517d4b706 > > --- /dev/null > > +++ b/UefiCpuPkg/Library/SmmCpuSyncLib/SmmCpuSyncLib.c > > @@ -0,0 +1,652 @@ > > +/** @file > > + SMM CPU Sync lib implementation. > > + > > + The lib provides 3 sets of APIs: > > + 1. ContextInit/ContextDeinit/ContextReset: > > + > > + ContextInit() is called in driver's entrypoint to allocate and ini= tialize the > > SMM CPU Sync context. > > + ContextDeinit() is called in driver's unload function to deinitial= ize the > > SMM CPU Sync context. > > + ContextReset() is called by one of CPUs after all CPUs are ready t= o exit > > SMI, which allows CPU to > > + check into the next SMI from this point. > > + > > + 2. GetArrivedCpuCount/CheckInCpu/CheckOutCpu/LockDoor: > > + When SMI happens, all processors including BSP enter to SMM mode b= y > > calling CheckInCpu(). > > + CheckOutCpu() can be called in error handling flow for the CPU who > > calls CheckInCpu() earlier. > > + The elected BSP calls LockDoor() so that CheckInCpu() and > > CheckOutCpu() will return the error code after that. > > + GetArrivedCpuCount() returns the number of checked-in CPUs. > > + > > + 3. WaitForAPs/ReleaseOneAp/WaitForBsp/ReleaseBsp > > + WaitForAPs() & ReleaseOneAp() are called from BSP to wait the numb= er > > of APs and release one specific AP. > > + WaitForBsp() & ReleaseBsp() are called from APs to wait and releas= e > > BSP. > > + The 4 APIs are used to synchronize the running flow among BSP and > > APs. > > + BSP and AP Sync flow can be easy understand as below: > > + BSP: ReleaseOneAp --> AP: WaitForBsp > > + BSP: WaitForAPs <-- AP: ReleaseBsp > > + > > + Copyright (c) 2023, Intel Corporation. All rights reserved.
> > + SPDX-License-Identifier: BSD-2-Clause-Patent > > + > > +**/ > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > + > > +/// > > +/// The implementation shall place one semaphore on exclusive cache li= ne > > for good performance. > > +/// > > +typedef volatile UINT32 SMM_CPU_SYNC_SEMAPHORE; > > + > > +typedef struct { > > + /// > > + /// Used for control each CPU continue run or wait for signal > > + /// > > + SMM_CPU_SYNC_SEMAPHORE *Run; > > +} SMM_CPU_SYNC_SEMAPHORE_FOR_EACH_CPU; > > + > > +struct SMM_CPU_SYNC_CONTEXT { > > + /// > > + /// Indicate all CPUs in the system. > > + /// > > + UINTN NumberOfCpus; > > + /// > > + /// Address of semaphores. > > + /// > > + VOID *SemBuffer; > > + /// > > + /// Size of semaphores. > > + /// > > + UINTN SemBufferPages; > > + /// > > + /// Before the door is locked, CpuCount stores the arrived CPU count= . > > + /// After the door is locked, CpuCount is set to -1 indicating the d= oor is > > locked. > > + /// ArrivedCpuCountUponLock stores the arrived CPU count then. > > + /// > > + UINTN > > ArrivedCpuCountUponLock; > > + /// > > + /// Indicate CPUs entered SMM before lock door. > > + /// > > + SMM_CPU_SYNC_SEMAPHORE *CpuCount; > > + /// > > + /// Define an array of structure for each CPU semaphore due to the s= ize > > alignment > > + /// requirement. With the array of structure for each CPU semaphore,= it's > > easy to > > + /// reach the specific CPU with CPU Index for its own semaphore acce= ss: > > CpuSem[CpuIndex]. > > + /// > > + SMM_CPU_SYNC_SEMAPHORE_FOR_EACH_CPU CpuSem[]; > > +}; > > + > > +/** > > + Performs an atomic compare exchange operation to get semaphore. > > + The compare exchange operation must be performed using MP safe > > + mechanisms. > > + > > + @param[in,out] Sem IN: 32-bit unsigned integer > > + OUT: original integer - 1 if Sem is not locke= d. > > + OUT: MAX_UINT32 if Sem is locked. > > + > > + @retval Original integer - 1 if Sem is not locked. > > + MAX_UINT32 if Sem is locked. > > + > > +**/ > > +STATIC > > +UINT32 > > +InternalWaitForSemaphore ( > > + IN OUT volatile UINT32 *Sem > > + ) > > +{ > > + UINT32 Value; > > + > > + for ( ; ;) { > > + Value =3D *Sem; > > + if (Value =3D=3D MAX_UINT32) { > > + return Value; > > + } > > + > > + if ((Value !=3D 0) && > > + (InterlockedCompareExchange32 ( > > + (UINT32 *)Sem, > > + Value, > > + Value - 1 > > + ) =3D=3D Value)) > > + { > > + break; > > + } > > + > > + CpuPause (); > > + } > > + > > + return Value - 1; > > +} > > + > > +/** > > + Performs an atomic compare exchange operation to release semaphore. > > + The compare exchange operation must be performed using MP safe > > + mechanisms. > > + > > + @param[in,out] Sem IN: 32-bit unsigned integer > > + OUT: original integer + 1 if Sem is not locke= d. > > + OUT: MAX_UINT32 if Sem is locked. > > + > > + @retval Original integer + 1 if Sem is not locked. > > + MAX_UINT32 if Sem is locked. > > + > > +**/ > > +STATIC > > +UINT32 > > +InternalReleaseSemaphore ( > > + IN OUT volatile UINT32 *Sem > > + ) > > +{ > > + UINT32 Value; > > + > > + do { > > + Value =3D *Sem; > > + } while (Value + 1 !=3D 0 && > > + InterlockedCompareExchange32 ( > > + (UINT32 *)Sem, > > + Value, > > + Value + 1 > > + ) !=3D Value); > > + > > + if (Value =3D=3D MAX_UINT32) { > > + return Value; > > + } > > + > > + return Value + 1; > > +} > > + > > +/** > > + Performs an atomic compare exchange operation to lock semaphore. > > + The compare exchange operation must be performed using MP safe > > + mechanisms. > > + > > + @param[in,out] Sem IN: 32-bit unsigned integer > > + OUT: -1 > > + > > + @retval Original integer > > + > > +**/ > > +STATIC > > +UINT32 > > +InternalLockdownSemaphore ( > > + IN OUT volatile UINT32 *Sem > > + ) > > +{ > > + UINT32 Value; > > + > > + do { > > + Value =3D *Sem; > > + } while (InterlockedCompareExchange32 ( > > + (UINT32 *)Sem, > > + Value, > > + (UINT32)-1 > > + ) !=3D Value); > > + > > + return Value; > > +} > > + > > +/** > > + Create and initialize the SMM CPU Sync context. It is to allocate an= d > > initialize the > > + SMM CPU Sync context. > > + > > + If Context is NULL, then ASSERT(). > > + > > + @param[in] NumberOfCpus The number of Logical > > Processors in the system. > > + @param[out] Context Pointer to the new created and > > initialized SMM CPU Sync context object. > > + NULL will be returned if any > > error happen during init. > > + > > + @retval RETURN_SUCCESS The SMM CPU Sync context > > was successful created and initialized. > > + @retval RETURN_OUT_OF_RESOURCES There are not enough > > resources available to create and initialize SMM CPU Sync context. > > + @retval RETURN_BUFFER_TOO_SMALL Overflow happen > > + > > +**/ > > +RETURN_STATUS > > +EFIAPI > > +SmmCpuSyncContextInit ( > > + IN UINTN NumberOfCpus, > > + OUT SMM_CPU_SYNC_CONTEXT **Context > > + ) > > +{ > > + RETURN_STATUS Status; > > + UINTN ContextSize; > > + UINTN OneSemSize; > > + UINTN NumSem; > > + UINTN TotalSemSize; > > + UINTN SemAddr; > > + UINTN CpuIndex; > > + SMM_CPU_SYNC_SEMAPHORE_FOR_EACH_CPU *CpuSem; > > + > > + ASSERT (Context !=3D NULL); > > + > > + // > > + // Calculate ContextSize > > + // > > + Status =3D SafeUintnMult (NumberOfCpus, sizeof > > (SMM_CPU_SYNC_SEMAPHORE_FOR_EACH_CPU), &ContextSize); > > + if (RETURN_ERROR (Status)) { > > + return Status; > > + } > > + > > + Status =3D SafeUintnAdd (ContextSize, sizeof (SMM_CPU_SYNC_CONTEXT), > > &ContextSize); > > + if (RETURN_ERROR (Status)) { > > + return Status; > > + } > > + > > + // > > + // Allocate Buffer for Context > > + // > > + *Context =3D AllocatePool (ContextSize); > > + if (*Context =3D=3D NULL) { > > + return RETURN_OUT_OF_RESOURCES; > > + } > > + > > + (*Context)->ArrivedCpuCountUponLock =3D 0; > > + > > + // > > + // Save NumberOfCpus > > + // > > + (*Context)->NumberOfCpus =3D NumberOfCpus; > > + > > + // > > + // Calculate total semaphore size > > + // > > + OneSemSize =3D GetSpinLockProperties (); > > + ASSERT (sizeof (SMM_CPU_SYNC_SEMAPHORE) <=3D OneSemSize); > > + > > + Status =3D SafeUintnAdd (1, NumberOfCpus, &NumSem); > > + if (RETURN_ERROR (Status)) { > > + goto ON_ERROR; > > + } > > + > > + Status =3D SafeUintnMult (NumSem, OneSemSize, &TotalSemSize); > > + if (RETURN_ERROR (Status)) { > > + goto ON_ERROR; > > + } > > + > > + // > > + // Allocate for Semaphores in the *Context > > + // > > + (*Context)->SemBufferPages =3D EFI_SIZE_TO_PAGES (TotalSemSize); > > + (*Context)->SemBuffer =3D AllocatePages > > ((*Context)->SemBufferPages); > > + if ((*Context)->SemBuffer =3D=3D NULL) { > > + Status =3D RETURN_OUT_OF_RESOURCES; > > + goto ON_ERROR; > > + } > > + > > + // > > + // Assign Global Semaphore pointer > > + // > > + SemAddr =3D (UINTN)(*Context)->SemBuffer; > > + (*Context)->CpuCount =3D (SMM_CPU_SYNC_SEMAPHORE *)SemAddr; > > + *(*Context)->CpuCount =3D 0; > > + > > + SemAddr +=3D OneSemSize; > > + > > + // > > + // Assign CPU Semaphore pointer > > + // > > + CpuSem =3D (*Context)->CpuSem; > > + for (CpuIndex =3D 0; CpuIndex < NumberOfCpus; CpuIndex++) { > > + CpuSem->Run =3D (SMM_CPU_SYNC_SEMAPHORE *)SemAddr; > > + *CpuSem->Run =3D 0; > > + > > + CpuSem++; > > + SemAddr +=3D OneSemSize; > > + } > > + > > + return RETURN_SUCCESS; > > + > > +ON_ERROR: > > + FreePool (*Context); > > + return Status; > > +} > > + > > +/** > > + Deinit an allocated SMM CPU Sync context. The resources allocated in > > SmmCpuSyncContextInit() will > > + be freed. > > + > > + If Context is NULL, then ASSERT(). > > + > > + @param[in,out] Context Pointer to the SMM CPU Sync context > > object to be deinitialized. > > + > > +**/ > > +VOID > > +EFIAPI > > +SmmCpuSyncContextDeinit ( > > + IN OUT SMM_CPU_SYNC_CONTEXT *Context > > + ) > > +{ > > + ASSERT (Context !=3D NULL); > > + > > + FreePages (Context->SemBuffer, Context->SemBufferPages); > > + > > + FreePool (Context); > > +} > > + > > +/** > > + Reset SMM CPU Sync context. SMM CPU Sync context will be reset to th= e > > initialized state. > > + > > + This function is called by one of CPUs after all CPUs are ready to e= xit SMI, > > which allows CPU to > > + check into the next SMI from this point. > > + > > + If Context is NULL, then ASSERT(). > > + > > + @param[in,out] Context Pointer to the SMM CPU Sync context > > object to be reset. > > + > > +**/ > > +VOID > > +EFIAPI > > +SmmCpuSyncContextReset ( > > + IN OUT SMM_CPU_SYNC_CONTEXT *Context > > + ) > > +{ > > + ASSERT (Context !=3D NULL); > > + > > + Context->ArrivedCpuCountUponLock =3D 0; > > + *Context->CpuCount =3D 0; > > +} > > + > > +/** > > + Get current number of arrived CPU in SMI. > > + > > + BSP might need to know the current number of arrived CPU in SMI to > > make sure all APs > > + in SMI. This API can be for that purpose. > > + > > + If Context is NULL, then ASSERT(). > > + > > + @param[in] Context Pointer to the SMM CPU Sync context > > object. > > + > > + @retval Current number of arrived CPU in SMI. > > + > > +**/ > > +UINTN > > +EFIAPI > > +SmmCpuSyncGetArrivedCpuCount ( > > + IN SMM_CPU_SYNC_CONTEXT *Context > > + ) > > +{ > > + UINT32 Value; > > + > > + ASSERT (Context !=3D NULL); > > + > > + Value =3D *Context->CpuCount; > > + > > + if (Value =3D=3D (UINT32)-1) { > > + return Context->ArrivedCpuCountUponLock; > > + } > > + > > + return Value; > > +} > > + > > +/** > > + Performs an atomic operation to check in CPU. > > + > > + When SMI happens, all processors including BSP enter to SMM mode by > > calling SmmCpuSyncCheckInCpu(). > > + > > + If Context is NULL, then ASSERT(). > > + If CpuIndex exceeds the range of all CPUs in the system, then ASSERT= (). > > + > > + @param[in,out] Context Pointer to the SMM CPU Sync > > context object. > > + @param[in] CpuIndex Check in CPU index. > > + > > + @retval RETURN_SUCCESS Check in CPU (CpuIndex) > > successfully. > > + @retval RETURN_ABORTED Check in CPU failed due to > > SmmCpuSyncLockDoor() has been called by one elected CPU. > > + > > +**/ > > +RETURN_STATUS > > +EFIAPI > > +SmmCpuSyncCheckInCpu ( > > + IN OUT SMM_CPU_SYNC_CONTEXT *Context, > > + IN UINTN CpuIndex > > + ) > > +{ > > + ASSERT (Context !=3D NULL); > > + > > + ASSERT (CpuIndex < Context->NumberOfCpus); > > + > > + // > > + // Check to return if CpuCount has already been locked. > > + // > > + if (InternalReleaseSemaphore (Context->CpuCount) =3D=3D MAX_UINT32) = { > > + return RETURN_ABORTED; > > + } > > + > > + return RETURN_SUCCESS; > > +} > > + > > +/** > > + Performs an atomic operation to check out CPU. > > + > > + This function can be called in error handling flow for the CPU who c= alls > > CheckInCpu() earlier. > > + The caller shall make sure the CPU specified by CpuIndex has already > > checked-in. > > + > > + If Context is NULL, then ASSERT(). > > + If CpuIndex exceeds the range of all CPUs in the system, then ASSERT= (). > > + > > + @param[in,out] Context Pointer to the SMM CPU Sync > > context object. > > + @param[in] CpuIndex Check out CPU index. > > + > > + @retval RETURN_SUCCESS Check out CPU (CpuIndex) > > successfully. > > + @retval RETURN_ABORTED Check out CPU failed due to > > SmmCpuSyncLockDoor() has been called by one elected CPU. > > + > > +**/ > > +RETURN_STATUS > > +EFIAPI > > +SmmCpuSyncCheckOutCpu ( > > + IN OUT SMM_CPU_SYNC_CONTEXT *Context, > > + IN UINTN CpuIndex > > + ) > > +{ > > + ASSERT (Context !=3D NULL); > > + > > + ASSERT (CpuIndex < Context->NumberOfCpus); > > + > > + if (InternalWaitForSemaphore (Context->CpuCount) =3D=3D MAX_UINT32) = { > > + return RETURN_ABORTED; > > + } > > + > > + return RETURN_SUCCESS; > > +} > > + > > +/** > > + Performs an atomic operation lock door for CPU checkin and checkout. > > After this function: > > + CPU can not check in via SmmCpuSyncCheckInCpu(). > > + CPU can not check out via SmmCpuSyncCheckOutCpu(). > > + > > + The CPU specified by CpuIndex is elected to lock door. The caller sh= all > > make sure the CpuIndex > > + is the actual CPU calling this function to avoid the undefined behav= ior. > > + > > + If Context is NULL, then ASSERT(). > > + If CpuCount is NULL, then ASSERT(). > > + If CpuIndex exceeds the range of all CPUs in the system, then ASSERT= (). > > + > > + @param[in,out] Context Pointer to the SMM CPU Sync > > context object. > > + @param[in] CpuIndex Indicate which CPU to lock door. > > + @param[out] CpuCount Number of arrived CPU in SMI > > after look door. > > + > > +**/ > > +VOID > > +EFIAPI > > +SmmCpuSyncLockDoor ( > > + IN OUT SMM_CPU_SYNC_CONTEXT *Context, > > + IN UINTN CpuIndex, > > + OUT UINTN *CpuCount > > + ) > > +{ > > + ASSERT (Context !=3D NULL); > > + > > + ASSERT (CpuCount !=3D NULL); > > + > > + ASSERT (CpuIndex < Context->NumberOfCpus); > > + > > + // > > + // Temporarily record the CpuCount into the ArrivedCpuCountUponLock > > before lock door. > > + // Recording before lock door is to avoid the Context->CpuCount is l= ocked > > but possible > > + // Context->ArrivedCpuCountUponLock is not updated. > > + // > > + Context->ArrivedCpuCountUponLock =3D *Context->CpuCount; > > + > > + // > > + // Lock door operation > > + // > > + *CpuCount =3D InternalLockdownSemaphore (Context->CpuCount); > > + > > + // > > + // Update the ArrivedCpuCountUponLock > > + // > > + Context->ArrivedCpuCountUponLock =3D *CpuCount; > > +} > > + > > +/** > > + Used by the BSP to wait for APs. > > + > > + The number of APs need to be waited is specified by NumberOfAPs. The > > BSP is specified by BspIndex. > > + The caller shall make sure the BspIndex is the actual CPU calling th= is > > function to avoid the undefined behavior. > > + The caller shall make sure the NumberOfAPs have already checked-in t= o > > avoid the undefined behavior. > > + > > + If Context is NULL, then ASSERT(). > > + If NumberOfAPs >=3D All CPUs in system, then ASSERT(). > > + If BspIndex exceeds the range of all CPUs in the system, then ASSERT= (). > > + > > + Note: > > + This function is blocking mode, and it will return only after the nu= mber of > > APs released by > > + calling SmmCpuSyncReleaseBsp(): > > + BSP: WaitForAPs <-- AP: ReleaseBsp > > + > > + @param[in,out] Context Pointer to the SMM CPU Sync > > context object. > > + @param[in] NumberOfAPs Number of APs need to be > > waited by BSP. > > + @param[in] BspIndex The BSP Index to wait for APs. > > + > > +**/ > > +VOID > > +EFIAPI > > +SmmCpuSyncWaitForAPs ( > > + IN OUT SMM_CPU_SYNC_CONTEXT *Context, > > + IN UINTN NumberOfAPs, > > + IN UINTN BspIndex > > + ) > > +{ > > + UINTN Arrived; > > + > > + ASSERT (Context !=3D NULL); > > + > > + ASSERT (NumberOfAPs < Context->NumberOfCpus); > > + > > + ASSERT (BspIndex < Context->NumberOfCpus); > > + > > + for (Arrived =3D 0; Arrived < NumberOfAPs; Arrived++) { > > + InternalWaitForSemaphore (Context->CpuSem[BspIndex].Run); > > + } > > +} > > + > > +/** > > + Used by the BSP to release one AP. > > + > > + The AP is specified by CpuIndex. The BSP is specified by BspIndex. > > + The caller shall make sure the BspIndex is the actual CPU calling th= is > > function to avoid the undefined behavior. > > + The caller shall make sure the CpuIndex has already checked-in to av= oid > > the undefined behavior. > > + > > + If Context is NULL, then ASSERT(). > > + If CpuIndex =3D=3D BspIndex, then ASSERT(). > > + If BspIndex or CpuIndex exceed the range of all CPUs in the system, = then > > ASSERT(). > > + > > + @param[in,out] Context Pointer to the SMM CPU Sync > > context object. > > + @param[in] CpuIndex Indicate which AP need to be > > released. > > + @param[in] BspIndex The BSP Index to release AP. > > + > > +**/ > > +VOID > > +EFIAPI > > +SmmCpuSyncReleaseOneAp ( > > + IN OUT SMM_CPU_SYNC_CONTEXT *Context, > > + IN UINTN CpuIndex, > > + IN UINTN BspIndex > > + ) > > +{ > > + ASSERT (Context !=3D NULL); > > + > > + ASSERT (BspIndex !=3D CpuIndex); > > + > > + ASSERT (CpuIndex < Context->NumberOfCpus); > > + > > + ASSERT (BspIndex < Context->NumberOfCpus); > > + > > + InternalReleaseSemaphore (Context->CpuSem[CpuIndex].Run); > > +} > > + > > +/** > > + Used by the AP to wait BSP. > > + > > + The AP is specified by CpuIndex. > > + The caller shall make sure the CpuIndex is the actual CPU calling th= is > > function to avoid the undefined behavior. > > + The BSP is specified by BspIndex. > > + > > + If Context is NULL, then ASSERT(). > > + If CpuIndex =3D=3D BspIndex, then ASSERT(). > > + If BspIndex or CpuIndex exceed the range of all CPUs in the system, = then > > ASSERT(). > > + > > + Note: > > + This function is blocking mode, and it will return only after the AP= released > > by > > + calling SmmCpuSyncReleaseOneAp(): > > + BSP: ReleaseOneAp --> AP: WaitForBsp > > + > > + @param[in,out] Context Pointer to the SMM CPU Sync > > context object. > > + @param[in] CpuIndex Indicate which AP wait BSP. > > + @param[in] BspIndex The BSP Index to be waited. > > + > > +**/ > > +VOID > > +EFIAPI > > +SmmCpuSyncWaitForBsp ( > > + IN OUT SMM_CPU_SYNC_CONTEXT *Context, > > + IN UINTN CpuIndex, > > + IN UINTN BspIndex > > + ) > > +{ > > + ASSERT (Context !=3D NULL); > > + > > + ASSERT (BspIndex !=3D CpuIndex); > > + > > + ASSERT (CpuIndex < Context->NumberOfCpus); > > + > > + ASSERT (BspIndex < Context->NumberOfCpus); > > + > > + InternalWaitForSemaphore (Context->CpuSem[CpuIndex].Run); > > +} > > + > > +/** > > + Used by the AP to release BSP. > > + > > + The AP is specified by CpuIndex. > > + The caller shall make sure the CpuIndex is the actual CPU calling th= is > > function to avoid the undefined behavior. > > + The BSP is specified by BspIndex. > > + > > + If Context is NULL, then ASSERT(). > > + If CpuIndex =3D=3D BspIndex, then ASSERT(). > > + If BspIndex or CpuIndex exceed the range of all CPUs in the system, = then > > ASSERT(). > > + > > + @param[in,out] Context Pointer to the SMM CPU Sync > > context object. > > + @param[in] CpuIndex Indicate which AP release BSP. > > + @param[in] BspIndex The BSP Index to be released. > > + > > +**/ > > +VOID > > +EFIAPI > > +SmmCpuSyncReleaseBsp ( > > + IN OUT SMM_CPU_SYNC_CONTEXT *Context, > > + IN UINTN CpuIndex, > > + IN UINTN BspIndex > > + ) > > +{ > > + ASSERT (Context !=3D NULL); > > + > > + ASSERT (BspIndex !=3D CpuIndex); > > + > > + ASSERT (CpuIndex < Context->NumberOfCpus); > > + > > + ASSERT (BspIndex < Context->NumberOfCpus); > > + > > + InternalReleaseSemaphore (Context->CpuSem[BspIndex].Run); > > +} > > diff --git a/UefiCpuPkg/Library/SmmCpuSyncLib/SmmCpuSyncLib.inf > > b/UefiCpuPkg/Library/SmmCpuSyncLib/SmmCpuSyncLib.inf > > new file mode 100644 > > index 0000000000..6b0d49c30a > > --- /dev/null > > +++ b/UefiCpuPkg/Library/SmmCpuSyncLib/SmmCpuSyncLib.inf > > @@ -0,0 +1,34 @@ > > +## @file > > +# SMM CPU Synchronization lib. > > +# > > +# This is SMM CPU Synchronization lib used for SMM CPU sync operations= . > > +# > > +# Copyright (c) 2023, Intel Corporation. All rights reserved.
> > +# SPDX-License-Identifier: BSD-2-Clause-Patent > > +# > > +## > > + > > +[Defines] > > + INF_VERSION =3D 0x00010005 > > + BASE_NAME =3D SmmCpuSyncLib > > + FILE_GUID =3D > > 1ca1bc1a-16a4-46ef-956a-ca500fd3381f > > + MODULE_TYPE =3D DXE_SMM_DRIVER > > + LIBRARY_CLASS =3D > > SmmCpuSyncLib|DXE_SMM_DRIVER > > + > > +[Sources] > > + SmmCpuSyncLib.c > > + > > +[Packages] > > + MdePkg/MdePkg.dec > > + UefiCpuPkg/UefiCpuPkg.dec > > + > > +[LibraryClasses] > > + BaseLib > > + DebugLib > > + MemoryAllocationLib > > + SafeIntLib > > + SynchronizationLib > > + > > +[Pcd] > > + > > +[Protocols] > > diff --git a/UefiCpuPkg/UefiCpuPkg.dsc b/UefiCpuPkg/UefiCpuPkg.dsc > > index 074fd77461..28eed85bce 100644 > > --- a/UefiCpuPkg/UefiCpuPkg.dsc > > +++ b/UefiCpuPkg/UefiCpuPkg.dsc > > @@ -54,10 +54,11 @@ > > > > CacheMaintenanceLib|MdePkg/Library/BaseCacheMaintenanceLib/BaseCac > > heMaintenanceLib.inf > > PciLib|MdePkg/Library/BasePciLibPciExpress/BasePciLibPciExpress.inf > > PciExpressLib|MdePkg/Library/BasePciExpressLib/BasePciExpressLib.inf > > > > > SmmCpuPlatformHookLib|UefiCpuPkg/Library/SmmCpuPlatformHookLibNull > / > > SmmCpuPlatformHookLibNull.inf > > > > > SmmCpuFeaturesLib|UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeat > > uresLib.inf > > + > > SmmCpuSyncLib|UefiCpuPkg/Library/SmmCpuSyncLib/SmmCpuSyncLib.inf > > > > > PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BaseP > > eCoffGetEntryPointLib.inf > > > > > PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BasePe > > CoffExtraActionLibNull.inf > > > > > TpmMeasurementLib|MdeModulePkg/Library/TpmMeasurementLibNull/Tpm > > MeasurementLibNull.inf > > CcExitLib|UefiCpuPkg/Library/CcExitLibNull/CcExitLibNull.inf > > MicrocodeLib|UefiCpuPkg/Library/MicrocodeLib/MicrocodeLib.inf > > @@ -154,10 +155,11 @@ > > > > UefiCpuPkg/Library/RegisterCpuFeaturesLib/DxeRegisterCpuFeaturesLib.inf > > > > > UefiCpuPkg/Library/SmmCpuPlatformHookLibNull/SmmCpuPlatformHookLib > > Null.inf > > UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLib.inf > > UefiCpuPkg/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLibStm.inf > > > > > UefiCpuPkg/Library/SmmCpuFeaturesLib/StandaloneMmCpuFeaturesLib.inf > > + UefiCpuPkg/Library/SmmCpuSyncLib/SmmCpuSyncLib.inf > > UefiCpuPkg/Library/CcExitLibNull/CcExitLibNull.inf > > UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationPei.inf > > UefiCpuPkg/PiSmmCommunication/PiSmmCommunicationSmm.inf > > UefiCpuPkg/SecCore/SecCore.inf > > UefiCpuPkg/SecCore/SecCoreNative.inf > > -- > > 2.16.2.windows.1 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#112717): https://edk2.groups.io/g/devel/message/112717 Mute This Topic: https://groups.io/mt/103259036/7686176 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-