From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mga01.intel.com (mga01.intel.com [192.55.52.88]) by mx.groups.io with SMTP id smtpd.web11.4364.1665728340306286542 for ; Thu, 13 Oct 2022 23:19:00 -0700 Authentication-Results: mx.groups.io; dkim=fail reason="unable to parse pub key" header.i=@intel.com header.s=intel header.b=Nw3h1Hrp; spf=pass (domain: intel.com, ip: 192.55.52.88, mailfrom: ray.ni@intel.com) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1665728340; x=1697264340; h=from:to:cc:subject:date:message-id:references: in-reply-to:content-transfer-encoding:mime-version; bh=bAxuuOz+GxTF+22oRunt+kZJQXZWJMyUI7YOdSev7IQ=; b=Nw3h1Hrpm5tIovm9NnNAlU/ryRCcnZwIG8+zIosyfrrGqQYZTcW+3Fax EF9YuOMvcN8Et3aXNNUUCsxYFDoWIo6U8FPVLh3H0mKWgVb4LH2n+9F+j 3asCVD7a4U7fgKZDZ+6mzR+VBe3+s+UVGv4hjrjalwkkmFnWyVxEi3uBS ZVdKi1tUUVflK4nMDS2qWSJzwT7YQp8u7J3AQsA6C+1LksGLhif57O3qu UEkjicdrhhBA4eor0OE228nVh+nbdauFakA8pu9d5SDELKnqfMLt2thQG zMR6/sxYsJ5Tp6oe0JCQAb3tzfVYqPtuzR1lY+3uZmqzHYB5uAjbrNvyc A==; X-IronPort-AV: E=McAfee;i="6500,9779,10499"; a="331808702" X-IronPort-AV: E=Sophos;i="5.95,182,1661842800"; d="scan'208";a="331808702" Received: from orsmga001.jf.intel.com ([10.7.209.18]) by fmsmga101.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 13 Oct 2022 23:18:59 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6500,9779,10499"; a="660622190" X-IronPort-AV: E=Sophos;i="5.95,182,1661842800"; d="scan'208";a="660622190" Received: from fmsmsx601.amr.corp.intel.com ([10.18.126.81]) by orsmga001.jf.intel.com with ESMTP; 13 Oct 2022 23:18:59 -0700 Received: from fmsmsx608.amr.corp.intel.com (10.18.126.88) by fmsmsx601.amr.corp.intel.com (10.18.126.81) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.31; Thu, 13 Oct 2022 23:18:58 -0700 Received: from fmsmsx608.amr.corp.intel.com (10.18.126.88) by fmsmsx608.amr.corp.intel.com (10.18.126.88) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.31; Thu, 13 Oct 2022 23:18:58 -0700 Received: from fmsedg601.ED.cps.intel.com (10.1.192.135) by fmsmsx608.amr.corp.intel.com (10.18.126.88) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.31 via Frontend Transport; Thu, 13 Oct 2022 23:18:58 -0700 Received: from NAM12-MW2-obe.outbound.protection.outlook.com (104.47.66.46) by edgegateway.intel.com (192.55.55.70) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.1.2375.31; Thu, 13 Oct 2022 23:18:56 -0700 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=odJl1CTzqycM4Zh0dDarwpOXVqEoSZr9RkCN93AID62YWJ8kKhXlYfYq0t5UVO4uypa7B7ze79p3PDVsh2DTvLeo57s1Oa8eH6HHvvEQsZokgsu2ZilQ0YYLLnsCix4Kz3bEbGl614c27Gp5VbeJ+c4lqYvn1lncB82KJvuA0x1UHtZIx4uCSPG87pmCC5lyBlDMEyKPKlYRTdE5SWNEnmq0ZbRzsriycoMOu/LxcixuSRtxFbtuedv0EWiesRr6R2tb5DkHMOzmb4yHdfx2Fns/UCattTTCr9UnbVAL3ZsXt1/hbQzQbE+fzrdNFoPyE6CAlGz6kJypSJDQAo+z5Q== 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=iOBC+RvU89hSd+nSC0hmt/KEcK0IV/XHOeg98ZZnaoM=; b=oZARtx7lLurezs2sMUeIhvey3Z4Cbxo6Zlix24/r3wmzkmoXIiDZ/N4g0YwdGlyPoV1XFHZiwSXd3vW+1d7lktt2ApcDTkWaGelRVDKOc+oO773H0C1HLqNMqXOoLzsadot6E1GXamnGbcDc6oTiueIga1QTwoxbfwQtCmDxzMvtqG+9LHioj470iuhyml9aF9mJyASpoYEXFE4UphT0GywC0C4o3e8U+YuQagoG3qF4Kx6Ja5R9j7oDtqruUsLga2WAXO4rrDDdwz389cQCzqMvGfqWQHY6lxvL96HADu0nSWoB5+unm8kF97Q4wWieANQcMs8XJgw6DoDIJdAgJA== 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 Received: from MWHPR11MB1631.namprd11.prod.outlook.com (2603:10b6:301:10::10) by PH0PR11MB5110.namprd11.prod.outlook.com (2603:10b6:510:3f::13) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5723.26; Fri, 14 Oct 2022 06:18:46 +0000 Received: from MWHPR11MB1631.namprd11.prod.outlook.com ([fe80::483f:4bb5:a15f:f571]) by MWHPR11MB1631.namprd11.prod.outlook.com ([fe80::483f:4bb5:a15f:f571%11]) with mapi id 15.20.5723.026; Fri, 14 Oct 2022 06:18:45 +0000 From: "Ni, Ray" To: "Lou, Yun" , "devel@edk2.groups.io" CC: "Dong, Eric" , Laszlo Ersek , "Kumar, Rahul R" Subject: Re: [PATCH v2] UefiCpuPkg/Test: Add unit tests for MP service PPI and Protocol Thread-Topic: [PATCH v2] UefiCpuPkg/Test: Add unit tests for MP service PPI and Protocol Thread-Index: AQHY3K+Xc8IeJmi+UUaUxhMdWWKGoq4NcCpw Date: Fri, 14 Oct 2022 06:18:45 +0000 Message-ID: References: <20221010135242.5587-1-yun.lou@intel.com> In-Reply-To: <20221010135242.5587-1-yun.lou@intel.com> Accept-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: authentication-results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=intel.com; x-ms-publictraffictype: Email x-ms-traffictypediagnostic: MWHPR11MB1631:EE_|PH0PR11MB5110:EE_ x-ms-office365-filtering-correlation-id: 3ef8fca8-9307-452b-77fd-08daadabf2ff x-ms-exchange-senderadcheck: 1 x-ms-exchange-antispam-relay: 0 x-microsoft-antispam: BCL:0; x-microsoft-antispam-message-info: Z/0GyT+xdFB9fWf18QvdH4j5fwPBnyP16ulha0LwVxHPAL/U0DKCmcc8nLqHMXIoYITIjFOFTkS3wSmHDu6aq3G9Na4x1uPNx+Pq86Epmn7Bg0QgAGBNZOFdVvGbzjwBEKkd4cvTPOcrdlYbL/xYUZhckclrHPVI4yyNdeT8E542Zu2oNm4az8tYAjKrCNaEznYS4jucgfYUk8zQk42zN/nJScCPUcaQc4EZXMc/jm4yc0YIJvswmRNTKMUkSvu1z3UVMz2G3BxyMvjkvzhoTsXm8IrEKFV+58kpSZbGrBDucx1ZbUZ0CiqKnAEXfH5I23vsnYuBkdcPm2boRTe7yeaP8dyKL+AmGZQszgVWm7gnjewtLaxpKoht1qPMKUCXOm0DVHqVVToyuFFp0iwO32AI7fD7hF65fSHe9zfJmBsRIthYFvtz/UVyoVygvQHnHceTgYtBOxRGug9k3B5h3zK3XMnKJFnogNaBbbqn5uhlNxFvlibWAOKst3GswkkLvFY27BIJFpWZ8Un8an/nvEB1BIf0/JDd20SjQsLf+vZ7aCgJapwjfi745tcdQ+/wLJO6m+xpsqabjxfUhYnepRsjAuqyFEZiiIQ8kaTpeG62GfWrzgvY/O0vqKMJXK7N6kDLHlLeCP3KoxfIGYHI4+6abY39MLnq14BvGGhyJmMLYRmn69NIfrbHVsMr3arR6DFIG3iGGGxM6ncCdT9hotll/KuNmrZTPCwGkN6GupZ89QLkrCD0nXRK7Xd5ygkCla8xkjGK2rY7dQDduikf3w== x-forefront-antispam-report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:MWHPR11MB1631.namprd11.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230022)(376002)(396003)(366004)(346002)(136003)(39860400002)(451199015)(110136005)(33656002)(26005)(86362001)(30864003)(2906002)(38100700002)(5660300002)(82960400001)(122000001)(186003)(38070700005)(83380400001)(6506007)(53546011)(316002)(66556008)(7696005)(66446008)(66946007)(19627235002)(71200400001)(66476007)(76116006)(54906003)(478600001)(9686003)(55016003)(4326008)(8936002)(52536014)(64756008)(8676002)(107886003)(41300700001)(579004)(559001);DIR:OUT;SFP:1102; x-ms-exchange-antispam-messagedata-chunkcount: 1 x-ms-exchange-antispam-messagedata-0: =?us-ascii?Q?8LGdJioe9vbEkgcw2VwVaLwpvQn8hEbaR0WpZInU0Jxjm+aLbnqFPnJmLvuG?= =?us-ascii?Q?LqILCFGCnTkXTT/3Q/8q5BAY7uUUpPaOICzRNAQKkHQgBrRvpDYIvxnWqxYp?= =?us-ascii?Q?RqegMHNx25IB1zoIoWIKNrcQxhQ+zmVse0x3g16XstwM5SfY3CflpaIe318w?= =?us-ascii?Q?FKckJzsHxlkxbomKyR4imWNEGk1DwzBjsER3a9fl7ZvASTWxgGUzaC43Qrwu?= =?us-ascii?Q?nNRT1hylup4mp2aXw4GtU53m+CNBK/NGc/vUVLBjaHJ6qAf8jHTtNY+bGbxv?= =?us-ascii?Q?H2feJfHiGJq/aDzKviX6961etN4Q5+lrsi7pKX0A9NR1PbxbsJPVkdcqbSlX?= =?us-ascii?Q?FEeG1lqx2AyNzSwEW5r9zfBtdx8hdX1O+0v7eBgbSTDB+pvjnd/F/d4pRwc5?= =?us-ascii?Q?0rF8mzFJEyBybK4AG4sxTZQQqusjNYZhE5PJMgxjkUR44OTOglqgkL8GlmgH?= =?us-ascii?Q?p/SFLp1nvtkJAvLJ4uIjuEuVum4W6a3d2585L/OVMtFvfBFo5oHuMvhxYi5g?= =?us-ascii?Q?rYH/G/7kez7avcQQ5RRp51g9n92Xqpwbs9h4HY199xJPVIg97HHvIJbO83QL?= =?us-ascii?Q?Ei4G8UqBTrzWAvSjri+rRObV5v9tgY4e70qJXXX7WrA1w0C8MGIgBW1ZDc9D?= =?us-ascii?Q?VwsxdIJp5duu2x6ktSU3Myix1wjqEzSoRkCUx5wa6LBnYiQP0b6sE/OpBwvR?= =?us-ascii?Q?pUtTEtoRrdobfscsLZzy0/4IefpH5ovZt0jgC5jnwE3N9qD9hgMaXH6sX/qx?= =?us-ascii?Q?O+dIZAF5RPnRMJVecF/Kzss5xgvAFVgYJ8TkivYDK9qtivjiSNYs2OqQRQHJ?= =?us-ascii?Q?j4tszT9X6uqtM30lh7FqpMcoVQq1u/YbgMgN4vf6rwqTKc/EZh3fwudBKO4V?= =?us-ascii?Q?qozbbfPOXAcf86AyM9OzZpMqS+YYg415fPxXCNNnWX8srvy4+/U4+XphgpfV?= =?us-ascii?Q?foLzrJbiqMcp3wlN78W+1A4DMRBO6E0wc699P5YHXrcVuEaHY/HrYtRKj2pH?= =?us-ascii?Q?jrcGOZojuHWzdsToh/YEg7l/TTwVRTdDkGgewPXUkZs62HujxmnYC54O1N7a?= =?us-ascii?Q?Czg8WhWvSqu33qNdl3tCVrdCGk+yJPU61ao2PHr0TPo2O4tykKC0QcqdbKJv?= =?us-ascii?Q?BzFVRFGQ2Hj0RBmKOOdrcOipnHKS6E+75nGlHPBJqaMFesh3pNL8QKmyGenv?= =?us-ascii?Q?/cd27OJX9ZvFlub3h/0J3eeWePITpc70M7pxgGI3cCiUTewIRS3bGemOjHOH?= =?us-ascii?Q?x5YUSMr+eqiGaRrepwJ+hHapOhr/kZXJgneTMBpY23+DfwIob/U15FEMNdob?= =?us-ascii?Q?mEdCMHbxeew/YAhKTeGwhVL5npGcQl4cRsK3jTUX4J+jke2qFkE2AjTgyv0Z?= =?us-ascii?Q?CWpBETBMqLAIWaYo4MxmTBqXZ7Ru65BAufUPTgpc+tWfiTaHJLg77RJdJViu?= =?us-ascii?Q?vkYDW2iUno0VX0eCOLS3b6Qw2ZahodMiTVIpxTfOlKBvQTnRTwqJfZDg7Idv?= =?us-ascii?Q?/4iHsXgC1OStCj9RWo5kKsMI8kc35HBnTU2vDMvk1+VuBIE0LpJVJcRKnQlb?= =?us-ascii?Q?PZwzGSK8faGGteKMfBzD+x6zjK5zsLfHL6DV82mM?= MIME-Version: 1.0 X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-AuthSource: MWHPR11MB1631.namprd11.prod.outlook.com X-MS-Exchange-CrossTenant-Network-Message-Id: 3ef8fca8-9307-452b-77fd-08daadabf2ff X-MS-Exchange-CrossTenant-originalarrivaltime: 14 Oct 2022 06:18:45.4032 (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: PekuJm4D5YouMTxI5E6vH8oJYnQ91I0hcdVaXSICNzIfysZSyVBPdo06q25pQp8DwGtHiLNdbOF9LmoLe9NPwQ== X-MS-Exchange-Transport-CrossTenantHeadersStamped: PH0PR11MB5110 Return-Path: ray.ni@intel.com X-OriginatorOrg: intel.com Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Reviewed-by: Ray Ni > -----Original Message----- > From: Lou, Yun > Sent: Monday, October 10, 2022 9:53 PM > To: devel@edk2.groups.io > Cc: Lou, Yun ; Ni, Ray ; Dong, Eric = ; Laszlo Ersek > ; Kumar, Rahul R > Subject: [PATCH v2] UefiCpuPkg/Test: Add unit tests for MP service PPI an= d Protocol >=20 > From: Jason Lou >=20 > The code changes add unit tests based on current UnitTestFramework. > EdkiiPeiMpServices2PpiPeiUnitTest PEI module is used to test > EdkiiPeiMpServices2Ppi and EfiMpServiceProtocolDxeUnitTest DXE driver is > used to test EfiMpServiceProtocol. >=20 > Signed-off-by: Jason Lou > Cc: Ray Ni > Cc: Eric Dong > Cc: Laszlo Ersek > Cc: Rahul Kumar > --- > UefiCpuPkg/Test/UnitTest/EfiMpServicesPpiProtocol/EdkiiPeiMpServices2Ppi= UnitTest.c | 477 ++++++ > UefiCpuPkg/Test/UnitTest/EfiMpServicesPpiProtocol/EfiMpServiceProtocolUn= itTest.c | 244 +++ > UefiCpuPkg/Test/UnitTest/EfiMpServicesPpiProtocol/EfiMpServicesUnitTestC= ommom.c | 1776 > ++++++++++++++++++++ > UefiCpuPkg/Test/UnitTest/EfiMpServicesPpiProtocol/EdkiiPeiMpServices2Ppi= PeiUnitTest.inf | 46 + > UefiCpuPkg/Test/UnitTest/EfiMpServicesPpiProtocol/EfiMpServiceProtocolDx= eUnitTest.inf | 46 + > UefiCpuPkg/Test/UnitTest/EfiMpServicesPpiProtocol/EfiMpServicesUnitTestC= ommom.h | 627 +++++++ > UefiCpuPkg/UefiCpuPkg.dsc = | 5 + > 7 files changed, 3221 insertions(+) >=20 > diff --git a/UefiCpuPkg/Test/UnitTest/EfiMpServicesPpiProtocol/EdkiiPeiMp= Services2PpiUnitTest.c > b/UefiCpuPkg/Test/UnitTest/EfiMpServicesPpiProtocol/EdkiiPeiMpServices2Pp= iUnitTest.c > new file mode 100644 > index 0000000000..5c42a81d29 > --- /dev/null > +++ b/UefiCpuPkg/Test/UnitTest/EfiMpServicesPpiProtocol/EdkiiPeiMpService= s2PpiUnitTest.c > @@ -0,0 +1,477 @@ > +/** @file >=20 > + PEI Module to test APIs defined in EdkiiPeiMpServices2Ppi. >=20 > + >=20 > + Copyright (c) 2022, Intel Corporation. All rights reserved.
>=20 > + >=20 > + SPDX-License-Identifier: BSD-2-Clause-Patent >=20 > + >=20 > +**/ >=20 > + >=20 > +#include >=20 > +#include >=20 > +#include "EfiMpServicesUnitTestCommom.h" >=20 > + >=20 > +#define UNIT_TEST_NAME "EdkiiPeiMpServices2Ppi Unit Test" >=20 > +#define UNIT_TEST_VERSION "0.1" >=20 > + >=20 > +/** >=20 > + Get EDKII_PEI_MP_SERVICES2_PPI pointer. >=20 > + >=20 > + @param[out] MpServices Pointer to the buffer where EDKII_PEI_MP_SER= VICES2_PPI is stored. >=20 > + >=20 > + @retval EFI_SUCCESS EDKII_PEI_MP_SERVICES2_PPI interface is retu= rned >=20 > + @retval EFI_NOT_FOUND EDKII_PEI_MP_SERVICES2_PPI interface is not = found >=20 > +**/ >=20 > +EFI_STATUS >=20 > +MpServicesUnitTestGetMpServices ( >=20 > + OUT MP_SERVICES *MpServices >=20 > + ) >=20 > +{ >=20 > + return PeiServicesLocatePpi (&gEdkiiPeiMpServices2PpiGuid, 0, NULL, (V= OID **)&MpServices->Ppi); >=20 > +} >=20 > + >=20 > +/** >=20 > + Retrieve the number of logical processor in the platform and the numbe= r of those logical processors that >=20 > + are enabled on this boot. >=20 > + >=20 > + @param[in] MpServices MP_SERVICES structure. >=20 > + @param[out] NumberOfProcessors Pointer to the total number of logical= processors in the system, including >=20 > + the BSP and disabled APs. >=20 > + @param[out] NumberOfEnabledProcessors Pointer to the number of process= ors in the system that are enabled. >=20 > + >=20 > + @retval EFI_SUCCESS Retrieve the number of logical processor suc= cessfully >=20 > + @retval Others Retrieve the number of logical processor uns= uccessfully >=20 > +**/ >=20 > +EFI_STATUS >=20 > +MpServicesUnitTestGetNumberOfProcessors ( >=20 > + IN MP_SERVICES MpServices, >=20 > + OUT UINTN *NumberOfProcessors, >=20 > + OUT UINTN *NumberOfEnabledProcessors >=20 > + ) >=20 > +{ >=20 > + return MpServices.Ppi->GetNumberOfProcessors (MpServices.Ppi, NumberOf= Processors, > NumberOfEnabledProcessors); >=20 > +} >=20 > + >=20 > +/** >=20 > + Get detailed information on the requested logical processor. >=20 > + >=20 > + @param[in] MpServices MP_SERVICES structure. >=20 > + @param[in] ProcessorNumber The handle number of the processor. >=20 > + @param[out] ProcessorInfoBuffer Pointer to the buffer where the proces= sor information is stored. >=20 > + >=20 > + @retval EFI_SUCCESS Get information on the requested logical pro= cessor successfully >=20 > + @retval Others Get information on the requested logical pro= cessor unsuccessfully >=20 > +**/ >=20 > +EFI_STATUS >=20 > +MpServicesUnitTestGetProcessorInfo ( >=20 > + IN MP_SERVICES MpServices, >=20 > + IN UINTN ProcessorNumber, >=20 > + OUT EFI_PROCESSOR_INFORMATION *ProcessorInfoBuffer >=20 > + ) >=20 > +{ >=20 > + return MpServices.Ppi->GetProcessorInfo (MpServices.Ppi, ProcessorNumb= er, ProcessorInfoBuffer); >=20 > +} >=20 > + >=20 > +/** >=20 > + Execute a caller provided function on all enabled APs. >=20 > + >=20 > + @param[in] MpServices MP_SERVICES structure. >=20 > + @param[in] Procedure Pointer to the function to be run on enabled= APs of the system. >=20 > + @param[in] SingleThread If TRUE, then all the enabled APs execute th= e function specified by Procedure >=20 > + one by one, in ascending order of processor = handle number. >=20 > + If FALSE, then all the enabled APs execute t= he function specified by Procedure >=20 > + simultaneously. >=20 > + @param[in] TimeoutInMicroSeconds Indicates the time limit in microsec= onds for APs to return from Procedure, >=20 > + for blocking mode only. Zero means i= nfinity. >=20 > + @param[in] ProcedureArgument The parameter passed into Procedure = for all APs. >=20 > + >=20 > + @retval EFI_SUCCESS Execute a caller provided function on all en= abled APs successfully >=20 > + @retval Others Execute a caller provided function on all en= abled APs unsuccessfully >=20 > +**/ >=20 > +EFI_STATUS >=20 > +MpServicesUnitTestStartupAllAPs ( >=20 > + IN MP_SERVICES MpServices, >=20 > + IN EFI_AP_PROCEDURE Procedure, >=20 > + IN BOOLEAN SingleThread, >=20 > + IN UINTN TimeoutInMicroSeconds, >=20 > + IN VOID *ProcedureArgument >=20 > + ) >=20 > +{ >=20 > + return MpServices.Ppi->StartupAllAPs (MpServices.Ppi, Procedure, Singl= eThread, TimeoutInMicroSeconds, > ProcedureArgument); >=20 > +} >=20 > + >=20 > +/** >=20 > + Caller gets one enabled AP to execute a caller-provided function. >=20 > + >=20 > + @param[in] MpServices MP_SERVICES structure. >=20 > + @param[in] Procedure Pointer to the function to be run on enabled= APs of the system. >=20 > + @param[in] ProcessorNumber The handle number of the AP. >=20 > + @param[in] TimeoutInMicroSeconds Indicates the time limit in microsec= onds for APs to return from Procedure, >=20 > + for blocking mode only. Zero means i= nfinity. >=20 > + @param[in] ProcedureArgument The parameter passed into Procedure = for all APs. >=20 > + >=20 > + >=20 > + @retval EFI_SUCCESS Caller gets one enabled AP to execute a call= er-provided function successfully >=20 > + @retval Others Caller gets one enabled AP to execute a call= er-provided function unsuccessfully >=20 > +**/ >=20 > +EFI_STATUS >=20 > +MpServicesUnitTestStartupThisAP ( >=20 > + IN MP_SERVICES MpServices, >=20 > + IN EFI_AP_PROCEDURE Procedure, >=20 > + IN UINTN ProcessorNumber, >=20 > + IN UINTN TimeoutInMicroSeconds, >=20 > + IN VOID *ProcedureArgument >=20 > + ) >=20 > +{ >=20 > + return MpServices.Ppi->StartupThisAP (MpServices.Ppi, Procedure, Proce= ssorNumber, TimeoutInMicroSeconds, > ProcedureArgument); >=20 > +} >=20 > + >=20 > +/** >=20 > + Switch the requested AP to be the BSP from that point onward. >=20 > + >=20 > + @param[in] MpServices MP_SERVICES structure. >=20 > + @param[in] ProcessorNumber The handle number of AP that is to become = the new BSP. >=20 > + @param[in] EnableOldBSP If TRUE, the old BSP will be listed as an en= abled AP. Otherwise, it will be disabled. >=20 > + >=20 > + @retval EFI_SUCCESS Switch the requested AP to be the BSP succes= sfully >=20 > + @retval Others Switch the requested AP to be the BSP unsucc= essfully >=20 > +**/ >=20 > +EFI_STATUS >=20 > +MpServicesUnitTestSwitchBSP ( >=20 > + IN MP_SERVICES MpServices, >=20 > + IN UINTN ProcessorNumber, >=20 > + IN BOOLEAN EnableOldBSP >=20 > + ) >=20 > +{ >=20 > + return MpServices.Ppi->SwitchBSP (MpServices.Ppi, ProcessorNumber, Ena= bleOldBSP); >=20 > +} >=20 > + >=20 > +/** >=20 > + Caller enables or disables an AP from this point onward. >=20 > + >=20 > + @param[in] MpServices MP_SERVICES structure. >=20 > + @param[in] ProcessorNumber The handle number of the AP. >=20 > + @param[in] EnableAP Specifies the new state for the processor fo= r enabled, FALSE for disabled. >=20 > + @param[in] HealthFlag If not NULL, a pointer to a value that speci= fies the new health status of the AP. >=20 > + >=20 > + @retval EFI_SUCCESS Caller enables or disables an AP successfull= y. >=20 > + @retval Others Caller enables or disables an AP unsuccessfu= lly. >=20 > +**/ >=20 > +EFI_STATUS >=20 > +MpServicesUnitTestEnableDisableAP ( >=20 > + IN MP_SERVICES MpServices, >=20 > + IN UINTN ProcessorNumber, >=20 > + IN BOOLEAN EnableAP, >=20 > + IN UINT32 *HealthFlag >=20 > + ) >=20 > +{ >=20 > + return MpServices.Ppi->EnableDisableAP (MpServices.Ppi, ProcessorNumbe= r, EnableAP, HealthFlag); >=20 > +} >=20 > + >=20 > +/** >=20 > + Get the handle number for the calling processor. >=20 > + >=20 > + @param[in] MpServices MP_SERVICES structure. >=20 > + @param[out] ProcessorNumber The handle number for the calling processo= r. >=20 > + >=20 > + @retval EFI_SUCCESS Get the handle number for the calling proces= sor successfully. >=20 > + @retval Others Get the handle number for the calling proces= sor unsuccessfully. >=20 > +**/ >=20 > +EFI_STATUS >=20 > +MpServicesUnitTestWhoAmI ( >=20 > + IN MP_SERVICES MpServices, >=20 > + OUT UINTN *ProcessorNumber >=20 > + ) >=20 > +{ >=20 > + return MpServices.Ppi->WhoAmI (MpServices.Ppi, ProcessorNumber); >=20 > +} >=20 > + >=20 > +/** >=20 > + Execute a caller provided function on all enabled CPUs. >=20 > + >=20 > + @param[in] MpServices MP_SERVICES structure. >=20 > + @param[in] Procedure Pointer to the function to be run on enabled= CPUs of the system. >=20 > + @param[in] TimeoutInMicroSeconds Indicates the time limit in microsec= onds for APs to return from Procedure, >=20 > + for blocking mode only. Zero means i= nfinity. >=20 > + @param[in] ProcedureArgument The parameter passed into Procedure = for all enabled CPUs. >=20 > + >=20 > + @retval EFI_SUCCESS Execute a caller provided function on all en= abled CPUs successfully >=20 > + @retval Others Execute a caller provided function on all en= abled CPUs unsuccessfully >=20 > +**/ >=20 > +EFI_STATUS >=20 > +MpServicesUnitTestStartupAllCPUs ( >=20 > + IN MP_SERVICES MpServices, >=20 > + IN EFI_AP_PROCEDURE Procedure, >=20 > + IN UINTN TimeoutInMicroSeconds, >=20 > + IN VOID *ProcedureArgument >=20 > + ) >=20 > +{ >=20 > + return MpServices.Ppi->StartupAllCPUs (MpServices.Ppi, Procedure, Time= outInMicroSeconds, ProcedureArgument); >=20 > +} >=20 > + >=20 > +/** >=20 > + Infinite loop procedure to be run on specified AP. >=20 > + >=20 > + @param[in,out] Buffer The pointer to private data buffer. >=20 > +**/ >=20 > +VOID >=20 > +ApInfiniteLoopProcedure ( >=20 > + IN OUT VOID *Buffer >=20 > + ) >=20 > +{ >=20 > + EFI_STATUS Status; >=20 > + UINTN ProcessorNumber; >=20 > + volatile BOOLEAN InfiniteLoop; >=20 > + MP_SERVICE_UT_CONTEXT *LocalContext; >=20 > + >=20 > + LocalContext =3D (MP_SERVICE_UT_CONTEXT *)Buffer; >=20 > + >=20 > + Status =3D MpServicesUnitTestWhoAmI (LocalContext->MpServices, &Proces= sorNumber); >=20 > + ASSERT_EFI_ERROR (Status); >=20 > + >=20 > + if (ProcessorNumber =3D=3D LocalContext->BspNumber) { >=20 > + InfiniteLoop =3D FALSE; >=20 > + } else { >=20 > + InfiniteLoop =3D TRUE; >=20 > + } >=20 > + >=20 > + while (InfiniteLoop) { >=20 > + } >=20 > +} >=20 > + >=20 > +/** >=20 > + Procedure to run MP service StartupAllCPUs on AP. >=20 > + >=20 > + @param[in,out] Buffer The pointer to private data buffer. >=20 > +**/ >=20 > +VOID >=20 > +RunMpServiceStartupAllCPUsOnAp ( >=20 > + IN OUT VOID *Buffer >=20 > + ) >=20 > +{ >=20 > + MP_SERVICE_UT_CONTEXT *LocalContext; >=20 > + >=20 > + LocalContext =3D (MP_SERVICE_UT_CONTEXT *)Buffer; >=20 > + >=20 > + LocalContext->ApProcedureReturnStatus =3D MpServicesUnitTestStartupAll= CPUs ( >=20 > + LocalContext->MpServices, >=20 > + (EFI_AP_PROCEDURE)EmptyProce= dure, >=20 > + 0, >=20 > + NULL >=20 > + ); >=20 > +} >=20 > + >=20 > +/** >=20 > + Unit test of PEI MP service StartupAllCPU. >=20 > + All CPUs should execute the Procedure. >=20 > + >=20 > + @param[in] Context Context pointer for this test. >=20 > + >=20 > + @retval UNIT_TEST_PASSED The Unit test has completed and = the test >=20 > + case was successful. >=20 > + @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed= . >=20 > +**/ >=20 > +UNIT_TEST_STATUS >=20 > +EFIAPI >=20 > +TestStartupAllCPUs1 ( >=20 > + IN UNIT_TEST_CONTEXT Context >=20 > + ) >=20 > +{ >=20 > + EFI_STATUS Status; >=20 > + UINTN ProcessorIndex; >=20 > + MP_SERVICE_UT_CONTEXT *LocalContext; >=20 > + >=20 > + LocalContext =3D (MP_SERVICE_UT_CONTEXT *)Context; >=20 > + >=20 > + SetMem (LocalContext->CommonBuffer, LocalContext->NumberOfProcessors *= sizeof (*LocalContext- > >CommonBuffer), 0xFF); >=20 > + Status =3D MpServicesUnitTestStartupAllCPUs ( >=20 > + LocalContext->MpServices, >=20 > + (EFI_AP_PROCEDURE)StoreCpuNumbers, >=20 > + 0, >=20 > + (VOID *)LocalContext >=20 > + ); >=20 > + UT_ASSERT_NOT_EFI_ERROR (Status); >=20 > + >=20 > + for (ProcessorIndex =3D 0; ProcessorIndex < LocalContext->NumberOfProc= essors; ProcessorIndex++) { >=20 > + UT_ASSERT_TRUE (LocalContext->CommonBuffer[ProcessorIndex] =3D=3D Pr= ocessorIndex); >=20 > + } >=20 > + >=20 > + return UNIT_TEST_PASSED; >=20 > +} >=20 > + >=20 > +/** >=20 > + Unit test of PEI MP service StartupAllCPU. >=20 > + When this service is called from an AP, the return status should be EF= I_DEVICE_ERROR. >=20 > + >=20 > + @param[in] Context Context pointer for this test. >=20 > + >=20 > + @retval UNIT_TEST_PASSED The Unit test has completed and = the test >=20 > + case was successful. >=20 > + @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed= . >=20 > +**/ >=20 > +UNIT_TEST_STATUS >=20 > +EFIAPI >=20 > +TestStartupAllCPUs2 ( >=20 > + IN UNIT_TEST_CONTEXT Context >=20 > + ) >=20 > +{ >=20 > + EFI_STATUS Status; >=20 > + UINTN ApNumber; >=20 > + MP_SERVICE_UT_CONTEXT *LocalContext; >=20 > + >=20 > + LocalContext =3D (MP_SERVICE_UT_CONTEXT *)Context; >=20 > + >=20 > + for (ApNumber =3D 0; ApNumber < LocalContext->NumberOfProcessors; ApNu= mber++) { >=20 > + LocalContext->ApNumber =3D ApNumber; >=20 > + Status =3D MpServicesUnitTestStartupThisAP ( >=20 > + LocalContext->MpServices, >=20 > + (EFI_AP_PROCEDURE)RunMpServiceStartupAllC= PUsOnAp, >=20 > + ApNumber, >=20 > + 0, >=20 > + (VOID *)LocalContext >=20 > + ); >=20 > + >=20 > + if (ApNumber =3D=3D LocalContext->BspNumber) { >=20 > + UT_ASSERT_STATUS_EQUAL (Status, EFI_INVALID_PARAMETER); >=20 > + } else { >=20 > + UT_ASSERT_NOT_EFI_ERROR (Status); >=20 > + UT_ASSERT_STATUS_EQUAL (LocalContext->ApProcedureReturnStatus, EFI= _DEVICE_ERROR); >=20 > + } >=20 > + } >=20 > + >=20 > + return UNIT_TEST_PASSED; >=20 > +} >=20 > + >=20 > +/** >=20 > + Unit test of PEI MP service StartupAllCPU. >=20 > + When called with all CPUs timeout, the return status should be EFI_TIM= EOUT. >=20 > + >=20 > + @param[in] Context Context pointer for this test. >=20 > + >=20 > + @retval UNIT_TEST_PASSED The Unit test has completed and = the test >=20 > + case was successful. >=20 > + @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed= . >=20 > +**/ >=20 > +UNIT_TEST_STATUS >=20 > +EFIAPI >=20 > +TestStartupAllCPUs3 ( >=20 > + IN UNIT_TEST_CONTEXT Context >=20 > + ) >=20 > +{ >=20 > + EFI_STATUS Status; >=20 > + MP_SERVICE_UT_CONTEXT *LocalContext; >=20 > + >=20 > + LocalContext =3D (MP_SERVICE_UT_CONTEXT *)Context; >=20 > + >=20 > + Status =3D MpServicesUnitTestStartupAllCPUs ( >=20 > + LocalContext->MpServices, >=20 > + (EFI_AP_PROCEDURE)ApInfiniteLoopProcedure, >=20 > + RUN_PROCEDURE_TIMEOUT_VALUE, >=20 > + (VOID *)LocalContext >=20 > + ); >=20 > + UT_ASSERT_STATUS_EQUAL (Status, EFI_TIMEOUT); >=20 > + >=20 > + return UNIT_TEST_PASSED; >=20 > +} >=20 > + >=20 > +/** >=20 > + Create test suite and unit tests only for EdkiiPeiMpServices2Ppi. >=20 > + >=20 > + @param[in] Framework A pointer to the framework that is being per= sisted. >=20 > + @param[in] Context A pointer to the private data buffer. >=20 > + >=20 > + @retval EFI_SUCCESS Create test suite and unit tests successfull= y. >=20 > + @retval Others Create test suite and unit tests unsuccessfu= lly. >=20 > +**/ >=20 > +EFI_STATUS >=20 > +AddTestCaseOnlyForEdkiiPeiMpServices2Ppi ( >=20 > + IN UNIT_TEST_FRAMEWORK_HANDLE Framework, >=20 > + IN MP_SERVICE_UT_CONTEXT *Context >=20 > + ) >=20 > +{ >=20 > + EFI_STATUS Status; >=20 > + UNIT_TEST_SUITE_HANDLE MpServiceStartupAllCPUsTestSuite; >=20 > + >=20 > + MpServiceStartupAllCPUsTestSuite =3D NULL; >=20 > + >=20 > + // >=20 > + // Test StartupAllCPUs function >=20 > + // >=20 > + Status =3D CreateUnitTestSuite (&MpServiceStartupAllCPUsTestSuite, Fra= mework, "Execute a caller provided function on > all enabled CPUs", "MpServices.StartupAllCPUs", NULL, NULL); >=20 > + if (EFI_ERROR (Status)) { >=20 > + DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for MpServiceSta= rtupAllCPUs Test Suite\n")); >=20 > + return Status; >=20 > + } >=20 > + >=20 > + AddTestCase (MpServiceStartupAllCPUsTestSuite, "Test StartupAllCPUs 1"= , "TestStartupAllCPUs1", TestStartupAllCPUs1, > InitUTContext, CheckUTContext, Context); >=20 > + AddTestCase (MpServiceStartupAllCPUsTestSuite, "Test StartupAllCPUs 2"= , "TestStartupAllCPUs2", TestStartupAllCPUs2, > InitUTContext, CheckUTContext, Context); >=20 > + AddTestCase (MpServiceStartupAllCPUsTestSuite, "Test StartupAllCPUs 3"= , "TestStartupAllCPUs3", TestStartupAllCPUs3, > InitUTContext, CheckUTContext, Context); >=20 > + >=20 > + return EFI_SUCCESS; >=20 > +} >=20 > + >=20 > +/** >=20 > + Standard PEIM entry point for unit test execution from PEI. >=20 > + Initialize the unit test framework, suite, and unit tests for the Edki= iPeiMpServices2Ppi and run the unit test. >=20 > + >=20 > + @param[in] FileHandle Handle of the file being invoked. >=20 > + @param[in] PeiServices Pointer to PEI Services table. >=20 > + >=20 > +**/ >=20 > +EFI_STATUS >=20 > +EFIAPI >=20 > +PeiEntryPoint ( >=20 > + IN EFI_PEI_FILE_HANDLE FileHandle, >=20 > + IN CONST EFI_PEI_SERVICES **PeiServices >=20 > + ) >=20 > +{ >=20 > + EFI_STATUS Status; >=20 > + UNIT_TEST_FRAMEWORK_HANDLE Framework; >=20 > + MP_SERVICE_UT_CONTEXT Context; >=20 > + >=20 > + Framework =3D NULL; >=20 > + Context.MpServices.Ppi =3D NULL; >=20 > + Context.CommonBuffer =3D NULL; >=20 > + Context.DisabledApNumber =3D NULL; >=20 > + >=20 > + DEBUG ((DEBUG_INFO, "%a v%a\n", UNIT_TEST_NAME, UNIT_TEST_VERSION)); >=20 > + >=20 > + // >=20 > + // Start setting up the test framework for running the tests. >=20 > + // >=20 > + Status =3D InitUnitTestFramework (&Framework, UNIT_TEST_NAME, gEfiCall= erBaseName, UNIT_TEST_VERSION); >=20 > + if (EFI_ERROR (Status)) { >=20 > + DEBUG ((DEBUG_ERROR, "Failed in InitUnitTestFramework. Status =3D %r= \n", Status)); >=20 > + goto EXIT; >=20 > + } >=20 > + >=20 > + // >=20 > + // Create test suite and unit tests only for EdkiiPeiMpServices2Ppi. >=20 > + // >=20 > + Status =3D AddTestCaseOnlyForEdkiiPeiMpServices2Ppi (Framework, &Conte= xt); >=20 > + if (EFI_ERROR (Status)) { >=20 > + DEBUG ((DEBUG_ERROR, "Failed in AddTestCaseOnlyForEdkiiPeiMpServices= 2Ppi. Status =3D %r\n", Status)); >=20 > + goto EXIT; >=20 > + } >=20 > + >=20 > + // >=20 > + // Create test suite and unit tests for both EdkiiPeiMpServices2Ppi an= d EfiMpServiceProtocol. >=20 > + // >=20 > + Status =3D AddCommonTestCase (Framework, &Context); >=20 > + if (EFI_ERROR (Status)) { >=20 > + DEBUG ((DEBUG_ERROR, "Failed in AddCommonTestCase. Status =3D %r\n",= Status)); >=20 > + goto EXIT; >=20 > + } >=20 > + >=20 > + // >=20 > + // Execute the tests. >=20 > + // >=20 > + Status =3D RunAllTestSuites (Framework); >=20 > + >=20 > +EXIT: >=20 > + if (Framework !=3D NULL) { >=20 > + FreeUnitTestFramework (Framework); >=20 > + } >=20 > + >=20 > + return Status; >=20 > +} >=20 > diff --git a/UefiCpuPkg/Test/UnitTest/EfiMpServicesPpiProtocol/EfiMpServi= ceProtocolUnitTest.c > b/UefiCpuPkg/Test/UnitTest/EfiMpServicesPpiProtocol/EfiMpServiceProtocolU= nitTest.c > new file mode 100644 > index 0000000000..57f8ba3c06 > --- /dev/null > +++ b/UefiCpuPkg/Test/UnitTest/EfiMpServicesPpiProtocol/EfiMpServiceProto= colUnitTest.c > @@ -0,0 +1,244 @@ > +/** @file >=20 > + PEI Module to test EfiMpServiceProtocol. >=20 > + >=20 > + Copyright (c) 2022, Intel Corporation. All rights reserved.
>=20 > + >=20 > + SPDX-License-Identifier: BSD-2-Clause-Patent >=20 > + >=20 > +**/ >=20 > + >=20 > +#include >=20 > +#include >=20 > +#include "EfiMpServicesUnitTestCommom.h" >=20 > + >=20 > +#define UNIT_TEST_NAME "EfiMpServiceProtocol Unit Test" >=20 > +#define UNIT_TEST_VERSION "0.1" >=20 > + >=20 > +/** >=20 > + Get EFI_MP_SERVICES_PROTOCOL pointer. >=20 > + >=20 > + @param[out] MpServices Pointer to the buffer where EFI_MP_SERVICES_= PROTOCOL is stored >=20 > + >=20 > + @retval EFI_SUCCESS EFI_MP_SERVICES_PROTOCOL interface is return= ed >=20 > + @retval EFI_NOT_FOUND EFI_MP_SERVICES_PROTOCOL interface is not fo= und >=20 > +**/ >=20 > +EFI_STATUS >=20 > +MpServicesUnitTestGetMpServices ( >=20 > + OUT MP_SERVICES *MpServices >=20 > + ) >=20 > +{ >=20 > + return gBS->LocateProtocol (&gEfiMpServiceProtocolGuid, NULL, (VOID **= )&MpServices->Protocol); >=20 > +} >=20 > + >=20 > +/** >=20 > + Retrieve the number of logical processor in the platform and the numbe= r of those logical processors that >=20 > + are enabled on this boot. >=20 > + >=20 > + @param[in] MpServices MP_SERVICES structure. >=20 > + @param[out] NumberOfProcessors Pointer to the total number of logical= processors in the system, including >=20 > + the BSP and disabled APs. >=20 > + @param[out] NumberOfEnabledProcessors Pointer to the number of process= ors in the system that are enabled. >=20 > + >=20 > + @retval EFI_SUCCESS Retrieve the number of logical processor suc= cessfully >=20 > + @retval Others Retrieve the number of logical processor uns= uccessfully >=20 > +**/ >=20 > +EFI_STATUS >=20 > +MpServicesUnitTestGetNumberOfProcessors ( >=20 > + IN MP_SERVICES MpServices, >=20 > + OUT UINTN *NumberOfProcessors, >=20 > + OUT UINTN *NumberOfEnabledProcessors >=20 > + ) >=20 > +{ >=20 > + return MpServices.Protocol->GetNumberOfProcessors (MpServices.Protocol= , NumberOfProcessors, > NumberOfEnabledProcessors); >=20 > +} >=20 > + >=20 > +/** >=20 > + Get detailed information on the requested logical processor. >=20 > + >=20 > + @param[in] MpServices MP_SERVICES structure. >=20 > + @param[in] ProcessorNumber The handle number of the processor. >=20 > + @param[out] ProcessorInfoBuffer Pointer to the buffer where the proces= sor information is stored. >=20 > + >=20 > + @retval EFI_SUCCESS Get information on the requested logical pro= cessor successfully >=20 > + @retval Others Get information on the requested logical pro= cessor unsuccessfully >=20 > +**/ >=20 > +EFI_STATUS >=20 > +MpServicesUnitTestGetProcessorInfo ( >=20 > + IN MP_SERVICES MpServices, >=20 > + IN UINTN ProcessorNumber, >=20 > + OUT EFI_PROCESSOR_INFORMATION *ProcessorInfoBuffer >=20 > + ) >=20 > +{ >=20 > + return MpServices.Protocol->GetProcessorInfo (MpServices.Protocol, Pro= cessorNumber, ProcessorInfoBuffer); >=20 > +} >=20 > + >=20 > +/** >=20 > + Execute a caller provided function on all enabled APs. >=20 > + >=20 > + @param[in] MpServices MP_SERVICES structure. >=20 > + @param[in] Procedure Pointer to the function to be run on enabled= APs of the system. >=20 > + @param[in] SingleThread If TRUE, then all the enabled APs execute th= e function specified by Procedure >=20 > + one by one, in ascending order of processor = handle number. >=20 > + If FALSE, then all the enabled APs execute t= he function specified by Procedure >=20 > + simultaneously. >=20 > + @param[in] TimeoutInMicroSeconds Indicates the time limit in microsec= onds for APs to return from Procedure, >=20 > + for blocking mode only. Zero means i= nfinity. >=20 > + @param[in] ProcedureArgument The parameter passed into Procedure = for all APs. >=20 > + >=20 > + @retval EFI_SUCCESS Execute a caller provided function on all en= abled APs successfully >=20 > + @retval Others Execute a caller provided function on all en= abled APs unsuccessfully >=20 > +**/ >=20 > +EFI_STATUS >=20 > +MpServicesUnitTestStartupAllAPs ( >=20 > + IN MP_SERVICES MpServices, >=20 > + IN EFI_AP_PROCEDURE Procedure, >=20 > + IN BOOLEAN SingleThread, >=20 > + IN UINTN TimeoutInMicroSeconds, >=20 > + IN VOID *ProcedureArgument >=20 > + ) >=20 > +{ >=20 > + return MpServices.Protocol->StartupAllAPs (MpServices.Protocol, Proced= ure, SingleThread, NULL, > TimeoutInMicroSeconds, ProcedureArgument, NULL); >=20 > +} >=20 > + >=20 > +/** >=20 > + Caller gets one enabled AP to execute a caller-provided function. >=20 > + >=20 > + @param[in] MpServices MP_SERVICES structure. >=20 > + @param[in] Procedure Pointer to the function to be run on enabled= APs of the system. >=20 > + @param[in] ProcessorNumber The handle number of the AP. >=20 > + @param[in] TimeoutInMicroSeconds Indicates the time limit in microsec= onds for APs to return from Procedure, >=20 > + for blocking mode only. Zero means i= nfinity. >=20 > + @param[in] ProcedureArgument The parameter passed into Procedure = for all APs. >=20 > + >=20 > + >=20 > + @retval EFI_SUCCESS Caller gets one enabled AP to execute a call= er-provided function successfully >=20 > + @retval Others Caller gets one enabled AP to execute a call= er-provided function unsuccessfully >=20 > +**/ >=20 > +EFI_STATUS >=20 > +MpServicesUnitTestStartupThisAP ( >=20 > + IN MP_SERVICES MpServices, >=20 > + IN EFI_AP_PROCEDURE Procedure, >=20 > + IN UINTN ProcessorNumber, >=20 > + IN UINTN TimeoutInMicroSeconds, >=20 > + IN VOID *ProcedureArgument >=20 > + ) >=20 > +{ >=20 > + return MpServices.Protocol->StartupThisAP (MpServices.Protocol, Proced= ure, ProcessorNumber, NULL, > TimeoutInMicroSeconds, ProcedureArgument, NULL); >=20 > +} >=20 > + >=20 > +/** >=20 > + Switch the requested AP to be the BSP from that point onward. >=20 > + >=20 > + @param[in] MpServices MP_SERVICES structure. >=20 > + @param[in] ProcessorNumber The handle number of AP that is to become = the new BSP. >=20 > + @param[in] EnableOldBSP If TRUE, the old BSP will be listed as an en= abled AP. Otherwise, it will be disabled. >=20 > + >=20 > + @retval EFI_SUCCESS Switch the requested AP to be the BSP succes= sfully >=20 > + @retval Others Switch the requested AP to be the BSP unsucc= essfully >=20 > +**/ >=20 > +EFI_STATUS >=20 > +MpServicesUnitTestSwitchBSP ( >=20 > + IN MP_SERVICES MpServices, >=20 > + IN UINTN ProcessorNumber, >=20 > + IN BOOLEAN EnableOldBSP >=20 > + ) >=20 > +{ >=20 > + return MpServices.Protocol->SwitchBSP (MpServices.Protocol, ProcessorN= umber, EnableOldBSP); >=20 > +} >=20 > + >=20 > +/** >=20 > + Caller enables or disables an AP from this point onward. >=20 > + >=20 > + @param[in] MpServices MP_SERVICES structure. >=20 > + @param[in] ProcessorNumber The handle number of the AP. >=20 > + @param[in] EnableAP Specifies the new state for the processor fo= r enabled, FALSE for disabled. >=20 > + @param[in] HealthFlag If not NULL, a pointer to a value that speci= fies the new health status of the AP. >=20 > + >=20 > + @retval EFI_SUCCESS Caller enables or disables an AP successfull= y. >=20 > + @retval Others Caller enables or disables an AP unsuccessfu= lly. >=20 > +**/ >=20 > +EFI_STATUS >=20 > +MpServicesUnitTestEnableDisableAP ( >=20 > + IN MP_SERVICES MpServices, >=20 > + IN UINTN ProcessorNumber, >=20 > + IN BOOLEAN EnableAP, >=20 > + IN UINT32 *HealthFlag >=20 > + ) >=20 > +{ >=20 > + return MpServices.Protocol->EnableDisableAP (MpServices.Protocol, Proc= essorNumber, EnableAP, HealthFlag); >=20 > +} >=20 > + >=20 > +/** >=20 > + Get the handle number for the calling processor. >=20 > + >=20 > + @param[in] MpServices MP_SERVICES structure. >=20 > + @param[out] ProcessorNumber The handle number for the calling processo= r. >=20 > + >=20 > + @retval EFI_SUCCESS Get the handle number for the calling proces= sor successfully. >=20 > + @retval Others Get the handle number for the calling proces= sor unsuccessfully. >=20 > +**/ >=20 > +EFI_STATUS >=20 > +MpServicesUnitTestWhoAmI ( >=20 > + IN MP_SERVICES MpServices, >=20 > + OUT UINTN *ProcessorNumber >=20 > + ) >=20 > +{ >=20 > + return MpServices.Protocol->WhoAmI (MpServices.Protocol, ProcessorNumb= er); >=20 > +} >=20 > + >=20 > +/** >=20 > + Standard DXE driver or UEFI application entry point for unit test exec= ution from DXE or UEFI Shell. >=20 > + Initialize the unit test framework, suite, and unit tests for the EfiM= pServiceProtocol and run the unit test. >=20 > + >=20 > + @param[in] ImageHandle The firmware allocated handle for the EFI i= mage. >=20 > + @param[in] SystemTable A pointer to the EFI System Table. >=20 > + >=20 > +**/ >=20 > +EFI_STATUS >=20 > +EFIAPI >=20 > +DxeEntryPoint ( >=20 > + IN EFI_HANDLE ImageHandle, >=20 > + IN EFI_SYSTEM_TABLE *SystemTable >=20 > + ) >=20 > +{ >=20 > + EFI_STATUS Status; >=20 > + UNIT_TEST_FRAMEWORK_HANDLE Framework; >=20 > + MP_SERVICE_UT_CONTEXT Context; >=20 > + >=20 > + Framework =3D NULL; >=20 > + Context.MpServices.Ppi =3D NULL; >=20 > + Context.CommonBuffer =3D NULL; >=20 > + Context.DisabledApNumber =3D NULL; >=20 > + >=20 > + DEBUG ((DEBUG_INFO, "%a v%a\n", UNIT_TEST_NAME, UNIT_TEST_VERSION)); >=20 > + >=20 > + // >=20 > + // Start setting up the test framework for running the tests. >=20 > + // >=20 > + Status =3D InitUnitTestFramework (&Framework, UNIT_TEST_NAME, gEfiCall= erBaseName, UNIT_TEST_VERSION); >=20 > + if (EFI_ERROR (Status)) { >=20 > + DEBUG ((DEBUG_ERROR, "Failed in InitUnitTestFramework. Status =3D %r= \n", Status)); >=20 > + goto EXIT; >=20 > + } >=20 > + >=20 > + // >=20 > + // Create test suite and unit tests for both EdkiiPeiMpServices2Ppi an= d EfiMpServiceProtocol. >=20 > + // >=20 > + Status =3D AddCommonTestCase (Framework, &Context); >=20 > + if (EFI_ERROR (Status)) { >=20 > + DEBUG ((DEBUG_ERROR, "Failed in AddCommonTestCase. Status =3D %r\n",= Status)); >=20 > + goto EXIT; >=20 > + } >=20 > + >=20 > + // >=20 > + // Execute the tests. >=20 > + // >=20 > + Status =3D RunAllTestSuites (Framework); >=20 > + >=20 > +EXIT: >=20 > + if (Framework !=3D NULL) { >=20 > + FreeUnitTestFramework (Framework); >=20 > + } >=20 > + >=20 > + return Status; >=20 > +} >=20 > diff --git a/UefiCpuPkg/Test/UnitTest/EfiMpServicesPpiProtocol/EfiMpServi= cesUnitTestCommom.c > b/UefiCpuPkg/Test/UnitTest/EfiMpServicesPpiProtocol/EfiMpServicesUnitTest= Commom.c > new file mode 100644 > index 0000000000..ff79c5e8d4 > --- /dev/null > +++ b/UefiCpuPkg/Test/UnitTest/EfiMpServicesPpiProtocol/EfiMpServicesUnit= TestCommom.c > @@ -0,0 +1,1776 @@ > +/** @file >=20 > + Common code to test EdkiiPeiMpServices2Ppi and EfiMpServiceProtocol. >=20 > + >=20 > + Copyright (c) 2022, Intel Corporation. All rights reserved.
>=20 > + >=20 > + SPDX-License-Identifier: BSD-2-Clause-Patent >=20 > + >=20 > +**/ >=20 > + >=20 > +#include "EfiMpServicesUnitTestCommom.h" >=20 > + >=20 > +/** >=20 > + Prep routine for Unit test function. >=20 > + To save the ProcessorNumber of disabled AP and temporarily enable it. >=20 > + >=20 > + @param[in] Context Context pointer for this test. >=20 > + >=20 > + @retval UNIT_TEST_PASSED Prep routine runs successful. >=20 > + @retval UNIT_TEST_ERROR_TEST_FAILED Prep routine runs unsuccessful. >=20 > +**/ >=20 > +UNIT_TEST_STATUS >=20 > +EFIAPI >=20 > +InitUTContext ( >=20 > + IN UNIT_TEST_CONTEXT Context >=20 > + ) >=20 > +{ >=20 > + EFI_STATUS Status; >=20 > + UINTN NumberOfProcessors; >=20 > + UINTN NumberOfEnabledProcessors; >=20 > + UINTN NumberOfDisabledAPs; >=20 > + UINTN IndexOfDisabledAPs; >=20 > + UINTN BspNumber; >=20 > + UINTN ProcessorNumber; >=20 > + EFI_PROCESSOR_INFORMATION ProcessorInfoBuffer; >=20 > + MP_SERVICE_UT_CONTEXT *LocalContext; >=20 > + >=20 > + LocalContext =3D (MP_SERVICE_UT_CONTEXT *)Context; >=20 > + >=20 > + if (LocalContext->MpServices.Ppi !=3D NULL) { >=20 > + return UNIT_TEST_PASSED; >=20 > + } >=20 > + >=20 > + Status =3D MpServicesUnitTestGetMpServices (&LocalContext->MpServices)= ; >=20 > + UT_ASSERT_NOT_EFI_ERROR (Status); >=20 > + >=20 > + Status =3D MpServicesUnitTestWhoAmI (LocalContext->MpServices, &BspNum= ber); >=20 > + UT_ASSERT_NOT_EFI_ERROR (Status); >=20 > + DEBUG ((DEBUG_INFO, "%a: BspNumber =3D 0x%x\n", __FUNCTION__, BspNumbe= r)); >=20 > + >=20 > + Status =3D MpServicesUnitTestGetNumberOfProcessors ( >=20 > + LocalContext->MpServices, >=20 > + &NumberOfProcessors, >=20 > + &NumberOfEnabledProcessors >=20 > + ); >=20 > + UT_ASSERT_NOT_EFI_ERROR (Status); >=20 > + DEBUG (( >=20 > + DEBUG_INFO, >=20 > + "%a: NumberOfProcessors =3D 0x%x, NumberOfEnabledProcessors =3D 0x%x= \n", >=20 > + __FUNCTION__, >=20 > + NumberOfProcessors, >=20 > + NumberOfEnabledProcessors >=20 > + )); >=20 > + >=20 > + LocalContext->BspNumber =3D BspNumber; >=20 > + LocalContext->NumberOfProcessors =3D NumberOfProcessors; >=20 > + LocalContext->NumberOfEnabledProcessors =3D NumberOfEnabledProcessors; >=20 > + >=20 > + LocalContext->CommonBuffer =3D AllocatePages (EFI_SIZE_TO_PAGES (Numbe= rOfProcessors * sizeof (*LocalContext- > >CommonBuffer))); >=20 > + UT_ASSERT_NOT_NULL (LocalContext->CommonBuffer); >=20 > + >=20 > + NumberOfDisabledAPs =3D NumberOfProcessors - NumberOfEnabledProcessors= ; >=20 > + if ((NumberOfDisabledAPs > 0) && (LocalContext->DisabledApNumber =3D= =3D NULL)) { >=20 > + LocalContext->DisabledApNumber =3D AllocatePages (EFI_SIZE_TO_PAGES = (NumberOfDisabledAPs * sizeof > (*LocalContext->DisabledApNumber))); >=20 > + UT_ASSERT_NOT_NULL (LocalContext->DisabledApNumber); >=20 > + ZeroMem (LocalContext->DisabledApNumber, NumberOfDisabledAPs * sizeo= f (*LocalContext->DisabledApNumber)); >=20 > + >=20 > + for (ProcessorNumber =3D 0, IndexOfDisabledAPs =3D 0; ProcessorNumbe= r < LocalContext->NumberOfProcessors; > ProcessorNumber++) { >=20 > + Status =3D MpServicesUnitTestGetProcessorInfo ( >=20 > + LocalContext->MpServices, >=20 > + ProcessorNumber, >=20 > + &ProcessorInfoBuffer >=20 > + ); >=20 > + UT_ASSERT_NOT_EFI_ERROR (Status); >=20 > + >=20 > + if (!(ProcessorInfoBuffer.StatusFlag & PROCESSOR_ENABLED_BIT)) { >=20 > + // >=20 > + // Save ProcessorNumber of disabled AP. >=20 > + // >=20 > + LocalContext->DisabledApNumber[IndexOfDisabledAPs] =3D Processor= Number; >=20 > + IndexOfDisabledAPs++; >=20 > + >=20 > + DEBUG ((DEBUG_INFO, "%a: AP(0x%x) is disabled and temporarily en= able it.\n", __FUNCTION__, ProcessorNumber)); >=20 > + Status =3D MpServicesUnitTestEnableDisableAP ( >=20 > + LocalContext->MpServices, >=20 > + ProcessorNumber, >=20 > + TRUE, >=20 > + NULL >=20 > + ); >=20 > + UT_ASSERT_NOT_EFI_ERROR (Status); >=20 > + } >=20 > + } >=20 > + >=20 > + UT_ASSERT_TRUE (IndexOfDisabledAPs =3D=3D NumberOfDisabledAPs); >=20 > + } >=20 > + >=20 > + return UNIT_TEST_PASSED; >=20 > +} >=20 > + >=20 > +/** >=20 > + Cleanup routine for Unit test function. >=20 > + If any processor is disabled unexpectedly then reenable it. >=20 > + >=20 > + @param[in] Context Context pointer for this test. >=20 > +**/ >=20 > +VOID >=20 > +EFIAPI >=20 > +CheckUTContext ( >=20 > + IN UNIT_TEST_CONTEXT Context >=20 > + ) >=20 > +{ >=20 > + EFI_STATUS Status; >=20 > + UINTN NumberOfProcessors; >=20 > + UINTN NumberOfEnabledProcessors; >=20 > + UINTN BspNumber; >=20 > + UINTN ProcessorNumber; >=20 > + EFI_PROCESSOR_INFORMATION ProcessorInfoBuffer; >=20 > + MP_SERVICE_UT_CONTEXT *LocalContext; >=20 > + >=20 > + LocalContext =3D (MP_SERVICE_UT_CONTEXT *)Context; >=20 > + ASSERT (LocalContext->MpServices.Ppi !=3D NULL); >=20 > + >=20 > + Status =3D MpServicesUnitTestWhoAmI (LocalContext->MpServices, &BspNum= ber); >=20 > + ASSERT_EFI_ERROR (Status); >=20 > + >=20 > + if (BspNumber !=3D LocalContext->BspNumber) { >=20 > + LocalContext->BspNumber =3D BspNumber; >=20 > + DEBUG ((DEBUG_INFO, "%a: New BspNumber =3D 0x%x\n", __FUNCTION__, Bs= pNumber)); >=20 > + } >=20 > + >=20 > + ASSERT (BspNumber =3D=3D LocalContext->BspNumber); >=20 > + >=20 > + Status =3D MpServicesUnitTestGetNumberOfProcessors ( >=20 > + LocalContext->MpServices, >=20 > + &NumberOfProcessors, >=20 > + &NumberOfEnabledProcessors >=20 > + ); >=20 > + ASSERT_EFI_ERROR (Status); >=20 > + >=20 > + if (NumberOfProcessors !=3D LocalContext->NumberOfProcessors) { >=20 > + LocalContext->NumberOfProcessors =3D NumberOfProcessors; >=20 > + DEBUG ((DEBUG_INFO, "%a: New NumberOfProcessors =3D 0x%x\n", __FUNCT= ION__, NumberOfProcessors)); >=20 > + } >=20 > + >=20 > + if (NumberOfEnabledProcessors !=3D LocalContext->NumberOfProcessors) { >=20 > + DEBUG ((DEBUG_INFO, "%a: New NumberOfEnabledProcessors =3D 0x%x\n", = __FUNCTION__, > NumberOfEnabledProcessors)); >=20 > + >=20 > + for (ProcessorNumber =3D 0; ProcessorNumber < LocalContext->NumberOf= Processors; ProcessorNumber++) { >=20 > + Status =3D MpServicesUnitTestGetProcessorInfo ( >=20 > + LocalContext->MpServices, >=20 > + ProcessorNumber, >=20 > + &ProcessorInfoBuffer >=20 > + ); >=20 > + ASSERT_EFI_ERROR (Status); >=20 > + >=20 > + if (!(ProcessorInfoBuffer.StatusFlag & PROCESSOR_ENABLED_BIT)) { >=20 > + DEBUG ((DEBUG_INFO, "%a: AP(0x%x) is disabled unexpectedly and r= eenable it.\n", __FUNCTION__, > ProcessorNumber)); >=20 > + Status =3D MpServicesUnitTestEnableDisableAP ( >=20 > + LocalContext->MpServices, >=20 > + ProcessorNumber, >=20 > + TRUE, >=20 > + NULL >=20 > + ); >=20 > + ASSERT_EFI_ERROR (Status); >=20 > + } >=20 > + } >=20 > + } >=20 > +} >=20 > + >=20 > +/** >=20 > + Cleanup routine for Unit test function. >=20 > + It will be called by the last "AddTestCase" to restore AP state and fr= ee pointer. >=20 > + >=20 > + @param[in] Context Context pointer for this test. >=20 > +**/ >=20 > +VOID >=20 > +EFIAPI >=20 > +FreeUTContext ( >=20 > + IN UNIT_TEST_CONTEXT Context >=20 > + ) >=20 > +{ >=20 > + EFI_STATUS Status; >=20 > + UINTN NumberOfDisabledAPs; >=20 > + UINTN IndexOfDisabledAPs; >=20 > + MP_SERVICE_UT_CONTEXT *LocalContext; >=20 > + >=20 > + CheckUTContext (Context); >=20 > + >=20 > + LocalContext =3D (MP_SERVICE_UT_CONTEXT *)Context; >=20 > + ASSERT (LocalContext->MpServices.Ppi !=3D NULL); >=20 > + >=20 > + if (LocalContext->DisabledApNumber !=3D NULL) { >=20 > + NumberOfDisabledAPs =3D LocalContext->NumberOfProcessors - LocalCont= ext->NumberOfEnabledProcessors; >=20 > + for (IndexOfDisabledAPs =3D 0; IndexOfDisabledAPs < NumberOfDisabled= APs; IndexOfDisabledAPs++) { >=20 > + DEBUG (( >=20 > + DEBUG_INFO, >=20 > + "%a: Disable AP(0x%x) to restore its state.\n", >=20 > + __FUNCTION__, >=20 > + LocalContext->DisabledApNumber[IndexOfDisabledAPs] >=20 > + )); >=20 > + >=20 > + Status =3D MpServicesUnitTestEnableDisableAP ( >=20 > + LocalContext->MpServices, >=20 > + LocalContext->DisabledApNumber[IndexOfDisabledAPs], >=20 > + FALSE, >=20 > + NULL >=20 > + ); >=20 > + ASSERT_EFI_ERROR (Status); >=20 > + } >=20 > + >=20 > + FreePages (LocalContext->DisabledApNumber, EFI_SIZE_TO_PAGES (Number= OfDisabledAPs * sizeof (*LocalContext- > >DisabledApNumber))); >=20 > + } >=20 > + >=20 > + if (LocalContext->CommonBuffer !=3D NULL) { >=20 > + FreePages (LocalContext->CommonBuffer, EFI_SIZE_TO_PAGES (LocalConte= xt->NumberOfProcessors * sizeof > (*LocalContext->CommonBuffer))); >=20 > + } >=20 > +} >=20 > + >=20 > +/** >=20 > + Produce to store ProcessorNumber in the corresponding location of Comm= onBuffer. >=20 > + >=20 > + @param[in,out] Buffer The pointer to private data buffer. >=20 > +**/ >=20 > +VOID >=20 > +StoreCpuNumbers ( >=20 > + IN OUT VOID *Buffer >=20 > + ) >=20 > +{ >=20 > + EFI_STATUS Status; >=20 > + UINTN ProcessorNumber; >=20 > + MP_SERVICE_UT_CONTEXT *LocalContext; >=20 > + >=20 > + LocalContext =3D (MP_SERVICE_UT_CONTEXT *)Buffer; >=20 > + >=20 > + Status =3D MpServicesUnitTestWhoAmI (LocalContext->MpServices, &Proces= sorNumber); >=20 > + ASSERT_EFI_ERROR (Status); >=20 > + >=20 > + // >=20 > + // The layout of CommonBuffer (E.g. BspNumber =3D 2 and NumberOfProces= sors =3D 6) >=20 > + // Index 00 01 02 03 04 05 >=20 > + // Value 00 01 02 03 04 05 >=20 > + // >=20 > + if (ProcessorNumber < LocalContext->NumberOfProcessors) { >=20 > + LocalContext->CommonBuffer[ProcessorNumber] =3D ProcessorNumber; >=20 > + } >=20 > +} >=20 > + >=20 > +/** >=20 > + Produce to store the ProcessorNumber of AP execution order in CommonBu= ffer. >=20 > + >=20 > + @param[in,out] Buffer The pointer to private data buffer. >=20 > +**/ >=20 > +VOID >=20 > +StoreAPsExecutionOrder ( >=20 > + IN OUT VOID *Buffer >=20 > + ) >=20 > +{ >=20 > + EFI_STATUS Status; >=20 > + UINTN ProcessorNumber; >=20 > + UINTN *ApCounter; >=20 > + MP_SERVICE_UT_CONTEXT *LocalContext; >=20 > + >=20 > + LocalContext =3D (MP_SERVICE_UT_CONTEXT *)Buffer; >=20 > + >=20 > + Status =3D MpServicesUnitTestWhoAmI (LocalContext->MpServices, &Proces= sorNumber); >=20 > + ASSERT_EFI_ERROR (Status); >=20 > + >=20 > + // >=20 > + // The layout of CommonBuffer (E.g. BspNumber =3D 2 and NumberOfProces= sors =3D 6) >=20 > + // Index 00 01 02 03 04 05 >=20 > + // Value 00 01 03 04 05 ApCounter(5) >=20 > + // >=20 > + ApCounter =3D &(LocalContext->CommonBuffe= r[LocalContext->NumberOfProcessors - 1]); >=20 > + LocalContext->CommonBuffer[*ApCounter] =3D ProcessorNumber; >=20 > + (*ApCounter)++; >=20 > +} >=20 > + >=20 > +/** >=20 > + Infinite loop procedure to be run on specified CPU. >=20 > + >=20 > + @param[in,out] Buffer The pointer to private data buffer. >=20 > +**/ >=20 > +VOID >=20 > +InfiniteLoopProcedure ( >=20 > + IN OUT VOID *Buffer >=20 > + ) >=20 > +{ >=20 > + volatile BOOLEAN InfiniteLoop; >=20 > + >=20 > + InfiniteLoop =3D TRUE; >=20 > + >=20 > + while (InfiniteLoop) { >=20 > + } >=20 > +} >=20 > + >=20 > +/** >=20 > + Empty procedure to be run on specified CPU. >=20 > + >=20 > + @param[in,out] Buffer The pointer to private data buffer. >=20 > +**/ >=20 > +VOID >=20 > +EmptyProcedure ( >=20 > + IN OUT VOID *Buffer >=20 > + ) >=20 > +{ >=20 > +} >=20 > + >=20 > +/** >=20 > + Procedure to run MP service GetNumberOfProcessors on AP. >=20 > + >=20 > + @param[in,out] Buffer The pointer to private data buffer. >=20 > +**/ >=20 > +VOID >=20 > +RunMpServiceGetNumberOfProcessorsOnAp ( >=20 > + IN OUT VOID *Buffer >=20 > + ) >=20 > +{ >=20 > + UINTN NumberOfProcessors; >=20 > + UINTN NumberOfEnabledProcessors; >=20 > + MP_SERVICE_UT_CONTEXT *LocalContext; >=20 > + >=20 > + LocalContext =3D (MP_SERVICE_UT_CONTEXT *)Buffer; >=20 > + >=20 > + LocalContext->ApProcedureReturnStatus =3D MpServicesUnitTestGetNumberO= fProcessors ( >=20 > + LocalContext->MpServices, >=20 > + &NumberOfProcessors, >=20 > + &NumberOfEnabledProcessors >=20 > + ); >=20 > +} >=20 > + >=20 > +/** >=20 > + Procedure to run MP service GetProcessorInfo on AP. >=20 > + >=20 > + @param[in,out] Buffer The pointer to private data buffer. >=20 > +**/ >=20 > +VOID >=20 > +RunMpServiceGetProcessorInfoOnAp ( >=20 > + IN OUT VOID *Buffer >=20 > + ) >=20 > +{ >=20 > + EFI_PROCESSOR_INFORMATION ProcessorInfoBuffer; >=20 > + MP_SERVICE_UT_CONTEXT *LocalContext; >=20 > + >=20 > + LocalContext =3D (MP_SERVICE_UT_CONTEXT *)Buffer; >=20 > + >=20 > + LocalContext->ApProcedureReturnStatus =3D MpServicesUnitTestGetProcess= orInfo ( >=20 > + LocalContext->MpServices, >=20 > + LocalContext->ApNumber, >=20 > + &ProcessorInfoBuffer >=20 > + ); >=20 > +} >=20 > + >=20 > +/** >=20 > + Procedure to run MP service EnableDisableAP on AP. >=20 > + >=20 > + @param[in,out] Buffer The pointer to private data buffer. >=20 > +**/ >=20 > +VOID >=20 > +RunMpServiceEnableDisableAPOnAp ( >=20 > + IN OUT VOID *Buffer >=20 > + ) >=20 > +{ >=20 > + MP_SERVICE_UT_CONTEXT *LocalContext; >=20 > + >=20 > + LocalContext =3D (MP_SERVICE_UT_CONTEXT *)Buffer; >=20 > + >=20 > + LocalContext->ApProcedureReturnStatus =3D MpServicesUnitTestEnableDisa= bleAP ( >=20 > + LocalContext->MpServices, >=20 > + LocalContext->ApNumber, >=20 > + FALSE, >=20 > + NULL >=20 > + ); >=20 > +} >=20 > + >=20 > +/** >=20 > + Procedure to run MP service StartupThisAP on AP. >=20 > + >=20 > + @param[in,out] Buffer The pointer to private data buffer. >=20 > +**/ >=20 > +VOID >=20 > +RunMpServiceStartupThisAPOnAp ( >=20 > + IN OUT VOID *Buffer >=20 > + ) >=20 > +{ >=20 > + MP_SERVICE_UT_CONTEXT *LocalContext; >=20 > + >=20 > + LocalContext =3D (MP_SERVICE_UT_CONTEXT *)Buffer; >=20 > + >=20 > + LocalContext->ApProcedureReturnStatus =3D MpServicesUnitTestStartupThi= sAP ( >=20 > + LocalContext->MpServices, >=20 > + (EFI_AP_PROCEDURE)EmptyProce= dure, >=20 > + LocalContext->ApNumber, >=20 > + 0, >=20 > + NULL >=20 > + ); >=20 > +} >=20 > + >=20 > +/** >=20 > + Procedure to run MP service StartupAllAPs on AP. >=20 > + >=20 > + @param[in,out] Buffer The pointer to private data buffer. >=20 > +**/ >=20 > +VOID >=20 > +RunMpServiceStartupAllAPsOnAp ( >=20 > + IN OUT VOID *Buffer >=20 > + ) >=20 > +{ >=20 > + MP_SERVICE_UT_CONTEXT *LocalContext; >=20 > + >=20 > + LocalContext =3D (MP_SERVICE_UT_CONTEXT *)Buffer; >=20 > + >=20 > + LocalContext->ApProcedureReturnStatus =3D MpServicesUnitTestStartupAll= APs ( >=20 > + LocalContext->MpServices, >=20 > + (EFI_AP_PROCEDURE)EmptyProce= dure, >=20 > + FALSE, >=20 > + 0, >=20 > + NULL >=20 > + ); >=20 > +} >=20 > + >=20 > +/** >=20 > + Procedure to run MP service SwitchBSP on AP. >=20 > + >=20 > + @param[in,out] Buffer The pointer to private data buffer. >=20 > +**/ >=20 > +VOID >=20 > +RunMpServiceSwitchBSPOnAp ( >=20 > + IN OUT VOID *Buffer >=20 > + ) >=20 > +{ >=20 > + MP_SERVICE_UT_CONTEXT *LocalContext; >=20 > + >=20 > + LocalContext =3D (MP_SERVICE_UT_CONTEXT *)Buffer; >=20 > + >=20 > + LocalContext->ApProcedureReturnStatus =3D MpServicesUnitTestSwitchBSP = ( >=20 > + LocalContext->MpServices, >=20 > + LocalContext->ApNumber, >=20 > + TRUE >=20 > + ); >=20 > +} >=20 > + >=20 > +/** >=20 > + Unit test of MP service WhoAmI. >=20 > + The range of ProcessorNumber should be from 0 to NumberOfCPUs minus 1. >=20 > + The ProcessorNumbers of all CPUs are unique. >=20 > + >=20 > + @param[in] Context Context pointer for this test. >=20 > + >=20 > + @retval UNIT_TEST_PASSED The Unit test has completed and = the test >=20 > + case was successful. >=20 > + @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed= . >=20 > +**/ >=20 > +UNIT_TEST_STATUS >=20 > +EFIAPI >=20 > +TestWhoAmI1 ( >=20 > + IN UNIT_TEST_CONTEXT Context >=20 > + ) >=20 > +{ >=20 > + EFI_STATUS Status; >=20 > + UINTN ProcessorNumber; >=20 > + UINTN ProcessorIndex; >=20 > + MP_SERVICE_UT_CONTEXT *LocalContext; >=20 > + >=20 > + LocalContext =3D (MP_SERVICE_UT_CONTEXT *)Context; >=20 > + >=20 > + Status =3D MpServicesUnitTestWhoAmI ( >=20 > + LocalContext->MpServices, >=20 > + &ProcessorNumber >=20 > + ); >=20 > + UT_ASSERT_NOT_EFI_ERROR (Status); >=20 > + UT_ASSERT_TRUE (ProcessorNumber < LocalContext->NumberOfProcessors); >=20 > + >=20 > + SetMem (LocalContext->CommonBuffer, LocalContext->NumberOfProcessors *= sizeof (*LocalContext- > >CommonBuffer), 0xFF); >=20 > + LocalContext->CommonBuffer[ProcessorNumber] =3D ProcessorNumber; >=20 > + >=20 > + Status =3D MpServicesUnitTestStartupAllAPs ( >=20 > + LocalContext->MpServices, >=20 > + (EFI_AP_PROCEDURE)StoreCpuNumbers, >=20 > + FALSE, >=20 > + 0, >=20 > + (VOID *)LocalContext >=20 > + ); >=20 > + UT_ASSERT_NOT_EFI_ERROR (Status); >=20 > + >=20 > + // >=20 > + // The layout of CommonBuffer (E.g. BspNumber =3D 2 and NumberOfProces= sors =3D 6) >=20 > + // Index 00 01 02 03 04 05 >=20 > + // Value 00 01 02 03 04 05 >=20 > + // >=20 > + for (ProcessorIndex =3D 0; ProcessorIndex < LocalContext->NumberOfProc= essors; ProcessorIndex++) { >=20 > + UT_ASSERT_TRUE (LocalContext->CommonBuffer[ProcessorIndex] =3D=3D Pr= ocessorIndex); >=20 > + } >=20 > + >=20 > + return UNIT_TEST_PASSED; >=20 > +} >=20 > + >=20 > +/** >=20 > + Unit test of MP service GetNumberOfProcessors. >=20 > + NumberOfProcessors should be greater that 0 and not less than NumberOf= EnabledProcessors. >=20 > + >=20 > + @param[in] Context Context pointer for this test. >=20 > + >=20 > + @retval UNIT_TEST_PASSED The Unit test has completed and = the test >=20 > + case was successful. >=20 > + @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed= . >=20 > +**/ >=20 > +UNIT_TEST_STATUS >=20 > +EFIAPI >=20 > +TestGetNumberOfProcessors1 ( >=20 > + IN UNIT_TEST_CONTEXT Context >=20 > + ) >=20 > +{ >=20 > + EFI_STATUS Status; >=20 > + UINTN NumberOfProcessors; >=20 > + UINTN NumberOfEnabledProcessors; >=20 > + MP_SERVICE_UT_CONTEXT *LocalContext; >=20 > + >=20 > + LocalContext =3D (MP_SERVICE_UT_CONTEXT *)Context; >=20 > + >=20 > + Status =3D MpServicesUnitTestGetNumberOfProcessors ( >=20 > + LocalContext->MpServices, >=20 > + &NumberOfProcessors, >=20 > + &NumberOfEnabledProcessors >=20 > + ); >=20 > + UT_ASSERT_NOT_EFI_ERROR (Status); >=20 > + UT_ASSERT_TRUE (NumberOfProcessors > 0 && NumberOfProcessors >=3D Numb= erOfEnabledProcessors); >=20 > + >=20 > + return UNIT_TEST_PASSED; >=20 > +} >=20 > + >=20 > +/** >=20 > + Unit test of MP service GetNumberOfProcessors. >=20 > + When this service is called from an AP, the return status should be EF= I_DEVICE_ERROR. >=20 > + >=20 > + @param[in] Context Context pointer for this test. >=20 > + >=20 > + @retval UNIT_TEST_PASSED The Unit test has completed and = the test >=20 > + case was successful. >=20 > + @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed= . >=20 > +**/ >=20 > +UNIT_TEST_STATUS >=20 > +EFIAPI >=20 > +TestGetNumberOfProcessors2 ( >=20 > + IN UNIT_TEST_CONTEXT Context >=20 > + ) >=20 > +{ >=20 > + EFI_STATUS Status; >=20 > + UINTN ApNumber; >=20 > + MP_SERVICE_UT_CONTEXT *LocalContext; >=20 > + >=20 > + LocalContext =3D (MP_SERVICE_UT_CONTEXT *)Context; >=20 > + >=20 > + for (ApNumber =3D 0; ApNumber < LocalContext->NumberOfProcessors; ApNu= mber++) { >=20 > + LocalContext->ApNumber =3D ApNumber; >=20 > + Status =3D MpServicesUnitTestStartupThisAP ( >=20 > + LocalContext->MpServices, >=20 > + (EFI_AP_PROCEDURE)RunMpServiceGetNumberOf= ProcessorsOnAp, >=20 > + ApNumber, >=20 > + 0, >=20 > + (VOID *)LocalContext >=20 > + ); >=20 > + >=20 > + if (ApNumber =3D=3D LocalContext->BspNumber) { >=20 > + UT_ASSERT_STATUS_EQUAL (Status, EFI_INVALID_PARAMETER); >=20 > + } else { >=20 > + UT_ASSERT_NOT_EFI_ERROR (Status); >=20 > + UT_ASSERT_STATUS_EQUAL (LocalContext->ApProcedureReturnStatus, EFI= _DEVICE_ERROR); >=20 > + } >=20 > + } >=20 > + >=20 > + return UNIT_TEST_PASSED; >=20 > +} >=20 > + >=20 > +/** >=20 > + Unit test of MP service GetNumberOfProcessors. >=20 > + Call EnableDisableAP() to change the number of enabled AP. >=20 > + >=20 > + @param[in] Context Context pointer for this test. >=20 > + >=20 > + @retval UNIT_TEST_PASSED The Unit test has completed and = the test >=20 > + case was successful. >=20 > + @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed= . >=20 > +**/ >=20 > +UNIT_TEST_STATUS >=20 > +EFIAPI >=20 > +TestGetNumberOfProcessors3 ( >=20 > + IN UNIT_TEST_CONTEXT Context >=20 > + ) >=20 > +{ >=20 > + EFI_STATUS Status; >=20 > + UINTN ApNumber; >=20 > + UINTN NumberOfProcessors; >=20 > + UINTN NumberOfEnabledProcessors; >=20 > + MP_SERVICE_UT_CONTEXT *LocalContext; >=20 > + >=20 > + LocalContext =3D (MP_SERVICE_UT_CONTEXT *)Context; >=20 > + >=20 > + for (ApNumber =3D 0; ApNumber < LocalContext->NumberOfProcessors; ApNu= mber++) { >=20 > + Status =3D MpServicesUnitTestEnableDisableAP ( >=20 > + LocalContext->MpServices, >=20 > + ApNumber, >=20 > + FALSE, >=20 > + NULL >=20 > + ); >=20 > + >=20 > + if (ApNumber =3D=3D LocalContext->BspNumber) { >=20 > + UT_ASSERT_STATUS_EQUAL (Status, EFI_INVALID_PARAMETER); >=20 > + } else { >=20 > + UT_ASSERT_NOT_EFI_ERROR (Status); >=20 > + >=20 > + Status =3D MpServicesUnitTestGetNumberOfProcessors ( >=20 > + LocalContext->MpServices, >=20 > + &NumberOfProcessors, >=20 > + &NumberOfEnabledProcessors >=20 > + ); >=20 > + UT_ASSERT_NOT_EFI_ERROR (Status); >=20 > + UT_ASSERT_TRUE (NumberOfProcessors =3D=3D LocalContext->NumberOfPr= ocessors); >=20 > + >=20 > + if (ApNumber < LocalContext->BspNumber) { >=20 > + UT_ASSERT_TRUE (NumberOfEnabledProcessors =3D=3D LocalContext->N= umberOfProcessors - (ApNumber + 1)); >=20 > + } else { >=20 > + UT_ASSERT_TRUE (NumberOfEnabledProcessors =3D=3D LocalContext->N= umberOfProcessors - ApNumber); >=20 > + } >=20 > + } >=20 > + } >=20 > + >=20 > + for (ApNumber =3D 0; ApNumber < LocalContext->NumberOfProcessors; ApNu= mber++) { >=20 > + Status =3D MpServicesUnitTestEnableDisableAP ( >=20 > + LocalContext->MpServices, >=20 > + ApNumber, >=20 > + TRUE, >=20 > + NULL >=20 > + ); >=20 > + >=20 > + if (ApNumber =3D=3D LocalContext->BspNumber) { >=20 > + UT_ASSERT_STATUS_EQUAL (Status, EFI_INVALID_PARAMETER); >=20 > + } else { >=20 > + UT_ASSERT_NOT_EFI_ERROR (Status); >=20 > + >=20 > + Status =3D MpServicesUnitTestGetNumberOfProcessors ( >=20 > + LocalContext->MpServices, >=20 > + &NumberOfProcessors, >=20 > + &NumberOfEnabledProcessors >=20 > + ); >=20 > + UT_ASSERT_NOT_EFI_ERROR (Status); >=20 > + UT_ASSERT_TRUE (NumberOfProcessors =3D=3D LocalContext->NumberOfPr= ocessors); >=20 > + >=20 > + if (ApNumber < LocalContext->BspNumber) { >=20 > + UT_ASSERT_TRUE (NumberOfEnabledProcessors =3D=3D ApNumber + 2); >=20 > + } else { >=20 > + UT_ASSERT_TRUE (NumberOfEnabledProcessors =3D=3D ApNumber + 1); >=20 > + } >=20 > + } >=20 > + } >=20 > + >=20 > + return UNIT_TEST_PASSED; >=20 > +} >=20 > + >=20 > +/** >=20 > + Unit test of MP service GetProcessorInfo. >=20 > + When all the parameters are valid, all reserved bits of StatusFlag in = ProcessorInfoBuffer should be set to zero. >=20 > + When all the parameters are valid, the StatusFlag should not have an i= nvalid value (The BSP can never be in the disabled > state.). >=20 > + When called with nonexistent processor handle, the return status shoul= d be EFI_NOT_FOUND. >=20 > + >=20 > + @param[in] Context Context pointer for this test. >=20 > + >=20 > + @retval UNIT_TEST_PASSED The Unit test has completed and = the test >=20 > + case was successful. >=20 > + @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed= . >=20 > +**/ >=20 > +UNIT_TEST_STATUS >=20 > +EFIAPI >=20 > +TestGetProcessorInfo1 ( >=20 > + IN UNIT_TEST_CONTEXT Context >=20 > + ) >=20 > +{ >=20 > + EFI_STATUS Status; >=20 > + UINTN ProcessorNumber; >=20 > + EFI_PROCESSOR_INFORMATION ProcessorInfoBuffer; >=20 > + MP_SERVICE_UT_CONTEXT *LocalContext; >=20 > + >=20 > + LocalContext =3D (MP_SERVICE_UT_CONTEXT *)Context; >=20 > + >=20 > + for (ProcessorNumber =3D 0; ProcessorNumber <=3D LocalContext->NumberO= fProcessors; ProcessorNumber++) { >=20 > + Status =3D MpServicesUnitTestGetProcessorInfo ( >=20 > + LocalContext->MpServices, >=20 > + ProcessorNumber, >=20 > + &ProcessorInfoBuffer >=20 > + ); >=20 > + >=20 > + if (ProcessorNumber =3D=3D LocalContext->NumberOfProcessors) { >=20 > + UT_ASSERT_STATUS_EQUAL (Status, EFI_NOT_FOUND); >=20 > + } else { >=20 > + UT_ASSERT_NOT_EFI_ERROR (Status); >=20 > + UT_ASSERT_TRUE ((ProcessorInfoBuffer.StatusFlag & (UINT32) > ~(PROCESSOR_AS_BSP_BIT|PROCESSOR_ENABLED_BIT|PROCESSOR_HEALTH_STATUS_BIT)= ) =3D=3D 0); >=20 > + >=20 > + if (ProcessorNumber =3D=3D LocalContext->BspNumber) { >=20 > + UT_ASSERT_TRUE ((ProcessorInfoBuffer.StatusFlag & PROCESSOR_AS_B= SP_BIT) && (ProcessorInfoBuffer.StatusFlag > & PROCESSOR_ENABLED_BIT)); >=20 > + } else { >=20 > + UT_ASSERT_TRUE (!(ProcessorInfoBuffer.StatusFlag & PROCESSOR_AS_= BSP_BIT)); >=20 > + } >=20 > + } >=20 > + } >=20 > + >=20 > + return UNIT_TEST_PASSED; >=20 > +} >=20 > + >=20 > +/** >=20 > + Unit test of MP service GetProcessorInfo. >=20 > + When this service is called from an AP, the return status should be EF= I_DEVICE_ERROR. >=20 > + >=20 > + @param[in] Context Context pointer for this test. >=20 > + >=20 > + @retval UNIT_TEST_PASSED The Unit test has completed and = the test >=20 > + case was successful. >=20 > + @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed= . >=20 > +**/ >=20 > +UNIT_TEST_STATUS >=20 > +EFIAPI >=20 > +TestGetProcessorInfo2 ( >=20 > + IN UNIT_TEST_CONTEXT Context >=20 > + ) >=20 > +{ >=20 > + EFI_STATUS Status; >=20 > + UINTN ApNumber; >=20 > + MP_SERVICE_UT_CONTEXT *LocalContext; >=20 > + >=20 > + LocalContext =3D (MP_SERVICE_UT_CONTEXT *)Context; >=20 > + >=20 > + for (ApNumber =3D 0; ApNumber < LocalContext->NumberOfProcessors; ApNu= mber++) { >=20 > + LocalContext->ApNumber =3D ApNumber; >=20 > + Status =3D MpServicesUnitTestStartupThisAP ( >=20 > + LocalContext->MpServices, >=20 > + (EFI_AP_PROCEDURE)RunMpServiceGetProcesso= rInfoOnAp, >=20 > + ApNumber, >=20 > + 0, >=20 > + (VOID *)LocalContext >=20 > + ); >=20 > + >=20 > + if (ApNumber =3D=3D LocalContext->BspNumber) { >=20 > + UT_ASSERT_STATUS_EQUAL (Status, EFI_INVALID_PARAMETER); >=20 > + } else { >=20 > + UT_ASSERT_NOT_EFI_ERROR (Status); >=20 > + UT_ASSERT_STATUS_EQUAL (LocalContext->ApProcedureReturnStatus, EFI= _DEVICE_ERROR); >=20 > + } >=20 > + } >=20 > + >=20 > + return UNIT_TEST_PASSED; >=20 > +} >=20 > + >=20 > +/** >=20 > + Unit test of MP service EnableDisableAP. >=20 > + When called with BSP number, the return status should be EFI_INVALID_P= ARAMETER. >=20 > + When called with a nonexistent processor handle, the return status sho= uld be EFI_NOT_FOUND. >=20 > + The AP should be really Enable/Disabled. >=20 > + >=20 > + @param[in] Context Context pointer for this test. >=20 > + >=20 > + @retval UNIT_TEST_PASSED The Unit test has completed and = the test >=20 > + case was successful. >=20 > + @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed= . >=20 > +**/ >=20 > +UNIT_TEST_STATUS >=20 > +EFIAPI >=20 > +TestEnableDisableAP1 ( >=20 > + IN UNIT_TEST_CONTEXT Context >=20 > + ) >=20 > +{ >=20 > + EFI_STATUS Status; >=20 > + UINTN ApNumber; >=20 > + MP_SERVICE_UT_CONTEXT *LocalContext; >=20 > + >=20 > + LocalContext =3D (MP_SERVICE_UT_CONTEXT *)Context; >=20 > + >=20 > + for (ApNumber =3D 0; ApNumber <=3D LocalContext->NumberOfProcessors; A= pNumber++) { >=20 > + Status =3D MpServicesUnitTestEnableDisableAP ( >=20 > + LocalContext->MpServices, >=20 > + ApNumber, >=20 > + FALSE, >=20 > + NULL >=20 > + ); >=20 > + >=20 > + if (ApNumber =3D=3D LocalContext->BspNumber) { >=20 > + UT_ASSERT_STATUS_EQUAL (Status, EFI_INVALID_PARAMETER); >=20 > + } else if (ApNumber =3D=3D LocalContext->NumberOfProcessors) { >=20 > + UT_ASSERT_STATUS_EQUAL (Status, EFI_NOT_FOUND); >=20 > + } else { >=20 > + UT_ASSERT_NOT_EFI_ERROR (Status); >=20 > + >=20 > + Status =3D MpServicesUnitTestStartupThisAP ( >=20 > + LocalContext->MpServices, >=20 > + (EFI_AP_PROCEDURE)EmptyProcedure, >=20 > + ApNumber, >=20 > + 0, >=20 > + NULL >=20 > + ); >=20 > + UT_ASSERT_STATUS_EQUAL (Status, EFI_INVALID_PARAMETER); >=20 > + >=20 > + Status =3D MpServicesUnitTestEnableDisableAP ( >=20 > + LocalContext->MpServices, >=20 > + ApNumber, >=20 > + TRUE, >=20 > + NULL >=20 > + ); >=20 > + UT_ASSERT_NOT_EFI_ERROR (Status); >=20 > + >=20 > + Status =3D MpServicesUnitTestStartupThisAP ( >=20 > + LocalContext->MpServices, >=20 > + (EFI_AP_PROCEDURE)EmptyProcedure, >=20 > + ApNumber, >=20 > + 0, >=20 > + NULL >=20 > + ); >=20 > + UT_ASSERT_NOT_EFI_ERROR (Status); >=20 > + } >=20 > + } >=20 > + >=20 > + return UNIT_TEST_PASSED; >=20 > +} >=20 > + >=20 > +/** >=20 > + Unit test of MP service EnableDisableAP. >=20 > + When run this procedure on AP, the return status should be EFI_DEVICE_= ERROR. >=20 > + >=20 > + @param[in] Context Context pointer for this test. >=20 > + >=20 > + @retval UNIT_TEST_PASSED The Unit test has completed and = the test >=20 > + case was successful. >=20 > + @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed= . >=20 > +**/ >=20 > +UNIT_TEST_STATUS >=20 > +EFIAPI >=20 > +TestEnableDisableAP2 ( >=20 > + IN UNIT_TEST_CONTEXT Context >=20 > + ) >=20 > +{ >=20 > + EFI_STATUS Status; >=20 > + UINTN ApNumber; >=20 > + MP_SERVICE_UT_CONTEXT *LocalContext; >=20 > + >=20 > + LocalContext =3D (MP_SERVICE_UT_CONTEXT *)Context; >=20 > + >=20 > + for (ApNumber =3D 0; ApNumber < LocalContext->NumberOfProcessors; ApNu= mber++) { >=20 > + LocalContext->ApNumber =3D ApNumber; >=20 > + Status =3D MpServicesUnitTestStartupThisAP ( >=20 > + LocalContext->MpServices, >=20 > + (EFI_AP_PROCEDURE)RunMpServiceEnableDisab= leAPOnAp, >=20 > + ApNumber, >=20 > + 0, >=20 > + (VOID *)LocalContext >=20 > + ); >=20 > + >=20 > + if (ApNumber =3D=3D LocalContext->BspNumber) { >=20 > + UT_ASSERT_STATUS_EQUAL (Status, EFI_INVALID_PARAMETER); >=20 > + } else { >=20 > + UT_ASSERT_NOT_EFI_ERROR (Status); >=20 > + UT_ASSERT_STATUS_EQUAL (LocalContext->ApProcedureReturnStatus, EFI= _DEVICE_ERROR); >=20 > + } >=20 > + } >=20 > + >=20 > + return UNIT_TEST_PASSED; >=20 > +} >=20 > + >=20 > +/** >=20 > + Unit test of MP service EnableDisableAP. >=20 > + When run this procedure on AP, the return status should be EFI_DEVICE_= ERROR. >=20 > + >=20 > + @param[in] Context Context pointer for this test. >=20 > + >=20 > + @retval UNIT_TEST_PASSED The Unit test has completed and = the test >=20 > + case was successful. >=20 > + @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed= . >=20 > +**/ >=20 > +UNIT_TEST_STATUS >=20 > +EFIAPI >=20 > +TestEnableDisableAP3 ( >=20 > + IN UNIT_TEST_CONTEXT Context >=20 > + ) >=20 > +{ >=20 > + EFI_STATUS Status; >=20 > + UINTN ApNumber; >=20 > + EFI_PROCESSOR_INFORMATION ProcessorInfoBuffer; >=20 > + UINT32 OldHealthFlag; >=20 > + UINT32 NewHealthFlag; >=20 > + MP_SERVICE_UT_CONTEXT *LocalContext; >=20 > + >=20 > + LocalContext =3D (MP_SERVICE_UT_CONTEXT *)Context; >=20 > + >=20 > + for (ApNumber =3D 0; ApNumber < LocalContext->NumberOfProcessors; ApNu= mber++) { >=20 > + Status =3D MpServicesUnitTestGetProcessorInfo ( >=20 > + LocalContext->MpServices, >=20 > + ApNumber, >=20 > + &ProcessorInfoBuffer >=20 > + ); >=20 > + UT_ASSERT_NOT_EFI_ERROR (Status); >=20 > + >=20 > + OldHealthFlag =3D ProcessorInfoBuffer.StatusFlag & PROCESSOR_HEALTH_= STATUS_BIT; >=20 > + NewHealthFlag =3D OldHealthFlag ^ PROCESSOR_HEALTH_STATUS_BIT; >=20 > + Status =3D MpServicesUnitTestEnableDisableAP ( >=20 > + LocalContext->MpServices, >=20 > + ApNumber, >=20 > + TRUE, >=20 > + &NewHealthFlag >=20 > + ); >=20 > + >=20 > + if (ApNumber =3D=3D LocalContext->BspNumber) { >=20 > + UT_ASSERT_STATUS_EQUAL (Status, EFI_INVALID_PARAMETER); >=20 > + } else { >=20 > + UT_ASSERT_NOT_EFI_ERROR (Status); >=20 > + >=20 > + Status =3D MpServicesUnitTestGetProcessorInfo ( >=20 > + LocalContext->MpServices, >=20 > + ApNumber, >=20 > + &ProcessorInfoBuffer >=20 > + ); >=20 > + UT_ASSERT_NOT_EFI_ERROR (Status); >=20 > + UT_ASSERT_TRUE ((ProcessorInfoBuffer.StatusFlag & PROCESSOR_HEALTH= _STATUS_BIT) =3D=3D NewHealthFlag); >=20 > + >=20 > + Status =3D MpServicesUnitTestEnableDisableAP ( >=20 > + LocalContext->MpServices, >=20 > + ApNumber, >=20 > + TRUE, >=20 > + &OldHealthFlag >=20 > + ); >=20 > + UT_ASSERT_NOT_EFI_ERROR (Status); >=20 > + } >=20 > + } >=20 > + >=20 > + return UNIT_TEST_PASSED; >=20 > +} >=20 > + >=20 > +/** >=20 > + Unit test of MP service StartupThisAP. >=20 > + When called to startup a BSP, the return status should be EFI_INVALID_= PARAMETER. >=20 > + When called with a nonexistent processor handle, the return status sho= uld be EFI_NOT_FOUND. >=20 > + The requested AP should execute the Procedure when called by StartupTh= isAP. >=20 > + >=20 > + @param[in] Context Context pointer for this test. >=20 > + >=20 > + @retval UNIT_TEST_PASSED The Unit test has completed and = the test >=20 > + case was successful. >=20 > + @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed= . >=20 > +**/ >=20 > +UNIT_TEST_STATUS >=20 > +EFIAPI >=20 > +TestStartupThisAP1 ( >=20 > + IN UNIT_TEST_CONTEXT Context >=20 > + ) >=20 > +{ >=20 > + EFI_STATUS Status; >=20 > + UINTN ApNumber; >=20 > + UINTN ProcessorIndex; >=20 > + MP_SERVICE_UT_CONTEXT *LocalContext; >=20 > + >=20 > + LocalContext =3D (MP_SERVICE_UT_CONTEXT *)Context; >=20 > + >=20 > + for (ApNumber =3D 0; ApNumber <=3D LocalContext->NumberOfProcessors; A= pNumber++) { >=20 > + SetMem (LocalContext->CommonBuffer, LocalContext->NumberOfProcessors= * sizeof (*LocalContext- > >CommonBuffer), 0xFF); >=20 > + Status =3D MpServicesUnitTestStartupThisAP ( >=20 > + LocalContext->MpServices, >=20 > + (EFI_AP_PROCEDURE)StoreCpuNumbers, >=20 > + ApNumber, >=20 > + 0, >=20 > + (VOID *)LocalContext >=20 > + ); >=20 > + >=20 > + if (ApNumber =3D=3D LocalContext->BspNumber) { >=20 > + UT_ASSERT_STATUS_EQUAL (Status, EFI_INVALID_PARAMETER); >=20 > + } else if (ApNumber =3D=3D LocalContext->NumberOfProcessors) { >=20 > + UT_ASSERT_STATUS_EQUAL (Status, EFI_NOT_FOUND); >=20 > + } else { >=20 > + UT_ASSERT_NOT_EFI_ERROR (Status); >=20 > + >=20 > + for (ProcessorIndex =3D 0; ProcessorIndex < LocalContext->NumberOf= Processors; ProcessorIndex++) { >=20 > + UT_ASSERT_TRUE ( >=20 > + ((ProcessorIndex =3D=3D ApNumber) && (LocalContext->CommonBuff= er[ProcessorIndex] =3D=3D ProcessorIndex)) || >=20 > + ((ProcessorIndex !=3D ApNumber) && (LocalContext->CommonBuffer= [ProcessorIndex] =3D=3D (UINTN) ~0)) >=20 > + ); >=20 > + } >=20 > + } >=20 > + } >=20 > + >=20 > + return UNIT_TEST_PASSED; >=20 > +} >=20 > + >=20 > +/** >=20 > + Unit test of MP service StartupThisAP. >=20 > + When this service is called from an AP, the return status should be EF= I_DEVICE_ERROR. >=20 > + >=20 > + @param[in] Context Context pointer for this test. >=20 > + >=20 > + @retval UNIT_TEST_PASSED The Unit test has completed and = the test >=20 > + case was successful. >=20 > + @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed= . >=20 > +**/ >=20 > +UNIT_TEST_STATUS >=20 > +EFIAPI >=20 > +TestStartupThisAP2 ( >=20 > + IN UNIT_TEST_CONTEXT Context >=20 > + ) >=20 > +{ >=20 > + EFI_STATUS Status; >=20 > + UINTN ApNumber; >=20 > + MP_SERVICE_UT_CONTEXT *LocalContext; >=20 > + >=20 > + LocalContext =3D (MP_SERVICE_UT_CONTEXT *)Context; >=20 > + >=20 > + for (ApNumber =3D 0; ApNumber < LocalContext->NumberOfProcessors; ApNu= mber++) { >=20 > + LocalContext->ApNumber =3D ApNumber; >=20 > + Status =3D MpServicesUnitTestStartupThisAP ( >=20 > + LocalContext->MpServices, >=20 > + (EFI_AP_PROCEDURE)RunMpServiceStartupThis= APOnAp, >=20 > + ApNumber, >=20 > + 0, >=20 > + (VOID *)LocalContext >=20 > + ); >=20 > + >=20 > + if (ApNumber =3D=3D LocalContext->BspNumber) { >=20 > + UT_ASSERT_STATUS_EQUAL (Status, EFI_INVALID_PARAMETER); >=20 > + } else { >=20 > + UT_ASSERT_NOT_EFI_ERROR (Status); >=20 > + UT_ASSERT_STATUS_EQUAL (LocalContext->ApProcedureReturnStatus, EFI= _DEVICE_ERROR); >=20 > + } >=20 > + } >=20 > + >=20 > + return UNIT_TEST_PASSED; >=20 > +} >=20 > + >=20 > +/** >=20 > + Unit test of MP service StartupThisAP. >=20 > + When timeout expired before the requested AP has finished, the return = status should be EFI_TIMEOUT. >=20 > + >=20 > + @param[in] Context Context pointer for this test. >=20 > + >=20 > + @retval UNIT_TEST_PASSED The Unit test has completed and = the test >=20 > + case was successful. >=20 > + @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed= . >=20 > +**/ >=20 > +UNIT_TEST_STATUS >=20 > +EFIAPI >=20 > +TestStartupThisAP3 ( >=20 > + IN UNIT_TEST_CONTEXT Context >=20 > + ) >=20 > +{ >=20 > + EFI_STATUS Status; >=20 > + UINTN ApNumber; >=20 > + MP_SERVICE_UT_CONTEXT *LocalContext; >=20 > + >=20 > + LocalContext =3D (MP_SERVICE_UT_CONTEXT *)Context; >=20 > + >=20 > + for (ApNumber =3D 0; ApNumber < LocalContext->NumberOfProcessors; ApNu= mber++) { >=20 > + Status =3D MpServicesUnitTestStartupThisAP ( >=20 > + LocalContext->MpServices, >=20 > + (EFI_AP_PROCEDURE)InfiniteLoopProcedure, >=20 > + ApNumber, >=20 > + RUN_PROCEDURE_TIMEOUT_VALUE, >=20 > + NULL >=20 > + ); >=20 > + >=20 > + if (ApNumber =3D=3D LocalContext->BspNumber) { >=20 > + UT_ASSERT_STATUS_EQUAL (Status, EFI_INVALID_PARAMETER); >=20 > + } else { >=20 > + UT_ASSERT_STATUS_EQUAL (Status, EFI_TIMEOUT); >=20 > + } >=20 > + } >=20 > + >=20 > + return UNIT_TEST_PASSED; >=20 > +} >=20 > + >=20 > +/** >=20 > + Unit test of MP service StartupThisAP. >=20 > + When called with disabled AP, the return status should be EFI_INVALID_= PARAMETER. >=20 > + >=20 > + @param[in] Context Context pointer for this test. >=20 > + >=20 > + @retval UNIT_TEST_PASSED The Unit test has completed and = the test >=20 > + case was successful. >=20 > + @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed= . >=20 > +**/ >=20 > +UNIT_TEST_STATUS >=20 > +EFIAPI >=20 > +TestStartupThisAP4 ( >=20 > + IN UNIT_TEST_CONTEXT Context >=20 > + ) >=20 > +{ >=20 > + EFI_STATUS Status; >=20 > + UINTN ApNumber; >=20 > + MP_SERVICE_UT_CONTEXT *LocalContext; >=20 > + >=20 > + LocalContext =3D (MP_SERVICE_UT_CONTEXT *)Context; >=20 > + >=20 > + for (ApNumber =3D 0; ApNumber < LocalContext->NumberOfProcessors; ApNu= mber++) { >=20 > + Status =3D MpServicesUnitTestEnableDisableAP ( >=20 > + LocalContext->MpServices, >=20 > + ApNumber, >=20 > + FALSE, >=20 > + NULL >=20 > + ); >=20 > + >=20 > + if (ApNumber =3D=3D LocalContext->BspNumber) { >=20 > + UT_ASSERT_STATUS_EQUAL (Status, EFI_INVALID_PARAMETER); >=20 > + } else { >=20 > + UT_ASSERT_NOT_EFI_ERROR (Status); >=20 > + >=20 > + Status =3D MpServicesUnitTestStartupThisAP ( >=20 > + LocalContext->MpServices, >=20 > + (EFI_AP_PROCEDURE)EmptyProcedure, >=20 > + ApNumber, >=20 > + 0, >=20 > + NULL >=20 > + ); >=20 > + UT_ASSERT_STATUS_EQUAL (Status, EFI_INVALID_PARAMETER); >=20 > + >=20 > + Status =3D MpServicesUnitTestEnableDisableAP ( >=20 > + LocalContext->MpServices, >=20 > + ApNumber, >=20 > + TRUE, >=20 > + NULL >=20 > + ); >=20 > + UT_ASSERT_NOT_EFI_ERROR (Status); >=20 > + >=20 > + Status =3D MpServicesUnitTestStartupThisAP ( >=20 > + LocalContext->MpServices, >=20 > + (EFI_AP_PROCEDURE)EmptyProcedure, >=20 > + ApNumber, >=20 > + 0, >=20 > + NULL >=20 > + ); >=20 > + UT_ASSERT_NOT_EFI_ERROR (Status); >=20 > + } >=20 > + } >=20 > + >=20 > + return UNIT_TEST_PASSED; >=20 > +} >=20 > + >=20 > +/** >=20 > + Unit test of MP service StartupAllAPs. >=20 > + All APs should execute the Procedure when called by StartupAllAPs. >=20 > + >=20 > + @param[in] Context Context pointer for this test. >=20 > + >=20 > + @retval UNIT_TEST_PASSED The Unit test has completed and = the test >=20 > + case was successful. >=20 > + @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed= . >=20 > +**/ >=20 > +UNIT_TEST_STATUS >=20 > +EFIAPI >=20 > +TestStartupAllAPs1 ( >=20 > + IN UNIT_TEST_CONTEXT Context >=20 > + ) >=20 > +{ >=20 > + EFI_STATUS Status; >=20 > + UINTN ProcessorIndex; >=20 > + MP_SERVICE_UT_CONTEXT *LocalContext; >=20 > + >=20 > + LocalContext =3D (MP_SERVICE_UT_CONTEXT *)Context; >=20 > + >=20 > + SetMem (LocalContext->CommonBuffer, LocalContext->NumberOfProcessors *= sizeof (*LocalContext- > >CommonBuffer), 0xFF); >=20 > + Status =3D MpServicesUnitTestStartupAllAPs ( >=20 > + LocalContext->MpServices, >=20 > + (EFI_AP_PROCEDURE)StoreCpuNumbers, >=20 > + FALSE, >=20 > + 0, >=20 > + (VOID *)LocalContext >=20 > + ); >=20 > + UT_ASSERT_NOT_EFI_ERROR (Status); >=20 > + >=20 > + for (ProcessorIndex =3D 0; ProcessorIndex < LocalContext->NumberOfProc= essors; ProcessorIndex++) { >=20 > + UT_ASSERT_TRUE ( >=20 > + ((ProcessorIndex =3D=3D LocalContext->BspNumber) && (LocalContext-= >CommonBuffer[ProcessorIndex] =3D=3D (UINTN) ~0)) > || >=20 > + ((ProcessorIndex !=3D LocalContext->BspNumber) && (LocalContext->C= ommonBuffer[ProcessorIndex] =3D=3D > ProcessorIndex)) >=20 > + ); >=20 > + } >=20 > + >=20 > + return UNIT_TEST_PASSED; >=20 > +} >=20 > + >=20 > +/** >=20 > + Unit test of MP service StartupAllAPs. >=20 > + When called in single thread, the return status should be EFI_SUCCESS = and AP executes in ascending order >=20 > + of processor handle number. >=20 > + >=20 > + @param[in] Context Context pointer for this test. >=20 > + >=20 > + @retval UNIT_TEST_PASSED The Unit test has completed and = the test >=20 > + case was successful. >=20 > + @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed= . >=20 > +**/ >=20 > +UNIT_TEST_STATUS >=20 > +EFIAPI >=20 > +TestStartupAllAPs2 ( >=20 > + IN UNIT_TEST_CONTEXT Context >=20 > + ) >=20 > +{ >=20 > + EFI_STATUS Status; >=20 > + UINTN ProcessorIndex; >=20 > + MP_SERVICE_UT_CONTEXT *LocalContext; >=20 > + >=20 > + LocalContext =3D (MP_SERVICE_UT_CONTEXT *)Context; >=20 > + >=20 > + ZeroMem (LocalContext->CommonBuffer, LocalContext->NumberOfProcessors = * sizeof (*LocalContext- > >CommonBuffer)); >=20 > + Status =3D MpServicesUnitTestStartupAllAPs ( >=20 > + LocalContext->MpServices, >=20 > + (EFI_AP_PROCEDURE)StoreAPsExecutionOrder, >=20 > + TRUE, >=20 > + 0, >=20 > + (VOID *)LocalContext >=20 > + ); >=20 > + UT_ASSERT_NOT_EFI_ERROR (Status); >=20 > + >=20 > + // >=20 > + // The layout of CommonBuffer (E.g. BspNumber =3D 2 and NumberOfProces= sors =3D 6) >=20 > + // Index 00 01 02 03 04 05 >=20 > + // Value 00 01 03 04 05 ApCounter(5) >=20 > + // >=20 > + for (ProcessorIndex =3D 0; ProcessorIndex < LocalContext->NumberOfProc= essors - 2; ProcessorIndex++) { >=20 > + UT_ASSERT_TRUE (LocalContext->CommonBuffer[ProcessorIndex] < LocalCo= ntext->CommonBuffer[ProcessorIndex + > 1]); >=20 > + } >=20 > + >=20 > + UT_ASSERT_EQUAL (LocalContext->CommonBuffer[LocalContext->NumberOfProc= essors - 1], LocalContext- > >NumberOfProcessors - 1); >=20 > + >=20 > + return UNIT_TEST_PASSED; >=20 > +} >=20 > + >=20 > +/** >=20 > + Unit test of MP service StartupAllAPs. >=20 > + When this service is called from an AP, the return status should be EF= I_DEVICE_ERROR. >=20 > + >=20 > + @param[in] Context Context pointer for this test. >=20 > + >=20 > + @retval UNIT_TEST_PASSED The Unit test has completed and = the test >=20 > + case was successful. >=20 > + @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed= . >=20 > +**/ >=20 > +UNIT_TEST_STATUS >=20 > +EFIAPI >=20 > +TestStartupAllAPs3 ( >=20 > + IN UNIT_TEST_CONTEXT Context >=20 > + ) >=20 > +{ >=20 > + EFI_STATUS Status; >=20 > + UINTN ApNumber; >=20 > + MP_SERVICE_UT_CONTEXT *LocalContext; >=20 > + >=20 > + LocalContext =3D (MP_SERVICE_UT_CONTEXT *)Context; >=20 > + >=20 > + for (ApNumber =3D 0; ApNumber < LocalContext->NumberOfProcessors; ApNu= mber++) { >=20 > + LocalContext->ApNumber =3D ApNumber; >=20 > + Status =3D MpServicesUnitTestStartupThisAP ( >=20 > + LocalContext->MpServices, >=20 > + (EFI_AP_PROCEDURE)RunMpServiceStartupAllA= PsOnAp, >=20 > + ApNumber, >=20 > + 0, >=20 > + (VOID *)LocalContext >=20 > + ); >=20 > + >=20 > + if (ApNumber =3D=3D LocalContext->BspNumber) { >=20 > + UT_ASSERT_STATUS_EQUAL (Status, EFI_INVALID_PARAMETER); >=20 > + } else { >=20 > + UT_ASSERT_NOT_EFI_ERROR (Status); >=20 > + UT_ASSERT_STATUS_EQUAL (LocalContext->ApProcedureReturnStatus, EFI= _DEVICE_ERROR); >=20 > + } >=20 > + } >=20 > + >=20 > + return UNIT_TEST_PASSED; >=20 > +} >=20 > + >=20 > +/** >=20 > + Unit test of MP service StartupAllAPs. >=20 > + When called with all AP timeout, the return status should be EFI_TIMEO= UT. >=20 > + >=20 > + @param[in] Context Context pointer for this test. >=20 > + >=20 > + @retval UNIT_TEST_PASSED The Unit test has completed and = the test >=20 > + case was successful. >=20 > + @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed= . >=20 > +**/ >=20 > +UNIT_TEST_STATUS >=20 > +EFIAPI >=20 > +TestStartupAllAPs4 ( >=20 > + IN UNIT_TEST_CONTEXT Context >=20 > + ) >=20 > +{ >=20 > + EFI_STATUS Status; >=20 > + MP_SERVICE_UT_CONTEXT *LocalContext; >=20 > + >=20 > + LocalContext =3D (MP_SERVICE_UT_CONTEXT *)Context; >=20 > + >=20 > + Status =3D MpServicesUnitTestStartupAllAPs ( >=20 > + LocalContext->MpServices, >=20 > + (EFI_AP_PROCEDURE)InfiniteLoopProcedure, >=20 > + TRUE, >=20 > + RUN_PROCEDURE_TIMEOUT_VALUE, >=20 > + NULL >=20 > + ); >=20 > + UT_ASSERT_STATUS_EQUAL (Status, EFI_TIMEOUT); >=20 > + >=20 > + Status =3D MpServicesUnitTestStartupAllAPs ( >=20 > + LocalContext->MpServices, >=20 > + (EFI_AP_PROCEDURE)InfiniteLoopProcedure, >=20 > + FALSE, >=20 > + RUN_PROCEDURE_TIMEOUT_VALUE, >=20 > + NULL >=20 > + ); >=20 > + UT_ASSERT_STATUS_EQUAL (Status, EFI_TIMEOUT); >=20 > + >=20 > + return UNIT_TEST_PASSED; >=20 > +} >=20 > + >=20 > +/** >=20 > + Unit test of MP service StartupAllAPs. >=20 > + When called with the empty Procedure on all disabled APs, the return s= tatus should be EFI_NOT_STARTED. >=20 > + >=20 > + @param[in] Context Context pointer for this test. >=20 > + >=20 > + @retval UNIT_TEST_PASSED The Unit test has completed and = the test >=20 > + case was successful. >=20 > + @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed= . >=20 > +**/ >=20 > +UNIT_TEST_STATUS >=20 > +EFIAPI >=20 > +TestStartupAllAPs5 ( >=20 > + IN UNIT_TEST_CONTEXT Context >=20 > + ) >=20 > +{ >=20 > + EFI_STATUS Status; >=20 > + UINTN ApNumber; >=20 > + MP_SERVICE_UT_CONTEXT *LocalContext; >=20 > + >=20 > + LocalContext =3D (MP_SERVICE_UT_CONTEXT *)Context; >=20 > + >=20 > + for (ApNumber =3D 0; ApNumber < LocalContext->NumberOfProcessors; ApNu= mber++) { >=20 > + Status =3D MpServicesUnitTestEnableDisableAP ( >=20 > + LocalContext->MpServices, >=20 > + ApNumber, >=20 > + FALSE, >=20 > + NULL >=20 > + ); >=20 > + >=20 > + if (ApNumber =3D=3D LocalContext->BspNumber) { >=20 > + UT_ASSERT_STATUS_EQUAL (Status, EFI_INVALID_PARAMETER); >=20 > + } else { >=20 > + UT_ASSERT_NOT_EFI_ERROR (Status); >=20 > + } >=20 > + } >=20 > + >=20 > + Status =3D MpServicesUnitTestStartupAllAPs ( >=20 > + LocalContext->MpServices, >=20 > + (EFI_AP_PROCEDURE)EmptyProcedure, >=20 > + FALSE, >=20 > + 0, >=20 > + NULL >=20 > + ); >=20 > + UT_ASSERT_STATUS_EQUAL (Status, EFI_NOT_STARTED); >=20 > + >=20 > + for (ApNumber =3D 0; ApNumber < LocalContext->NumberOfProcessors; ApNu= mber++) { >=20 > + Status =3D MpServicesUnitTestEnableDisableAP ( >=20 > + LocalContext->MpServices, >=20 > + ApNumber, >=20 > + TRUE, >=20 > + NULL >=20 > + ); >=20 > + >=20 > + if (ApNumber =3D=3D LocalContext->BspNumber) { >=20 > + UT_ASSERT_STATUS_EQUAL (Status, EFI_INVALID_PARAMETER); >=20 > + } else { >=20 > + UT_ASSERT_NOT_EFI_ERROR (Status); >=20 > + } >=20 > + } >=20 > + >=20 > + return UNIT_TEST_PASSED; >=20 > +} >=20 > + >=20 > +/** >=20 > + Unit test of MP service SwitchBSP. >=20 > + When switch current BSP to be BSP, the return status should be EFI_INV= ALID_PARAMETER. >=20 > + When switch nonexistent processor to be BSP, the return status should = be EFI_NOT_FOUND. >=20 > + After switch BSP, all APs(includes new AP) should execute the Procedur= e when called by StartupAllAP. >=20 > + >=20 > + @param[in] Context Context pointer for this test. >=20 > + >=20 > + @retval UNIT_TEST_PASSED The Unit test has completed and = the test >=20 > + case was successful. >=20 > + @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed= . >=20 > +**/ >=20 > +UNIT_TEST_STATUS >=20 > +EFIAPI >=20 > +TestSwitchBSP1 ( >=20 > + IN UNIT_TEST_CONTEXT Context >=20 > + ) >=20 > +{ >=20 > + EFI_STATUS Status; >=20 > + UINTN NewBspNumber; >=20 > + UINTN ProcessorIndex; >=20 > + MP_SERVICE_UT_CONTEXT *LocalContext; >=20 > + >=20 > + LocalContext =3D (MP_SERVICE_UT_CONTEXT *)Context; >=20 > + >=20 > + for (NewBspNumber =3D 0; NewBspNumber <=3D LocalContext->NumberOfProce= ssors; NewBspNumber++) { >=20 > + Status =3D MpServicesUnitTestSwitchBSP ( >=20 > + LocalContext->MpServices, >=20 > + NewBspNumber, >=20 > + TRUE >=20 > + ); >=20 > + >=20 > + if (NewBspNumber =3D=3D LocalContext->BspNumber) { >=20 > + UT_ASSERT_STATUS_EQUAL (Status, EFI_INVALID_PARAMETER); >=20 > + } else if (NewBspNumber =3D=3D LocalContext->NumberOfProcessors) { >=20 > + UT_ASSERT_STATUS_EQUAL (Status, EFI_NOT_FOUND); >=20 > + } else { >=20 > + UT_ASSERT_NOT_EFI_ERROR (Status); >=20 > + >=20 > + SetMem (LocalContext->CommonBuffer, LocalContext->NumberOfProcesso= rs * sizeof (*LocalContext- > >CommonBuffer), 0xFF); >=20 > + Status =3D MpServicesUnitTestStartupAllAPs ( >=20 > + LocalContext->MpServices, >=20 > + (EFI_AP_PROCEDURE)StoreCpuNumbers, >=20 > + FALSE, >=20 > + 0, >=20 > + (VOID *)LocalContext >=20 > + ); >=20 > + UT_ASSERT_NOT_EFI_ERROR (Status); >=20 > + >=20 > + for (ProcessorIndex =3D 0; ProcessorIndex < LocalContext->NumberOf= Processors; ProcessorIndex++) { >=20 > + UT_ASSERT_TRUE ( >=20 > + ((ProcessorIndex =3D=3D NewBspNumber) && (LocalContext->Common= Buffer[ProcessorIndex] =3D=3D (UINTN) ~0)) || >=20 > + ((ProcessorIndex !=3D NewBspNumber) && (LocalContext->CommonBu= ffer[ProcessorIndex] =3D=3D ProcessorIndex)) >=20 > + ); >=20 > + } >=20 > + >=20 > + Status =3D MpServicesUnitTestSwitchBSP ( >=20 > + LocalContext->MpServices, >=20 > + LocalContext->BspNumber, >=20 > + TRUE >=20 > + ); >=20 > + UT_ASSERT_NOT_EFI_ERROR (Status); >=20 > + } >=20 > + } >=20 > + >=20 > + return UNIT_TEST_PASSED; >=20 > +} >=20 > + >=20 > +/** >=20 > + Unit test of MP service SwitchBSP. >=20 > + When run this procedure on AP, the return status should be EFI_DEVICE_= ERROR. >=20 > + >=20 > + @param[in] Context Context pointer for this test. >=20 > + >=20 > + @retval UNIT_TEST_PASSED The Unit test has completed and = the test >=20 > + case was successful. >=20 > + @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed= . >=20 > +**/ >=20 > +UNIT_TEST_STATUS >=20 > +EFIAPI >=20 > +TestSwitchBSP2 ( >=20 > + IN UNIT_TEST_CONTEXT Context >=20 > + ) >=20 > +{ >=20 > + EFI_STATUS Status; >=20 > + UINTN ApNumber; >=20 > + MP_SERVICE_UT_CONTEXT *LocalContext; >=20 > + >=20 > + LocalContext =3D (MP_SERVICE_UT_CONTEXT *)Context; >=20 > + >=20 > + for (ApNumber =3D 0; ApNumber < LocalContext->NumberOfProcessors; ApNu= mber++) { >=20 > + LocalContext->ApNumber =3D ApNumber; >=20 > + Status =3D MpServicesUnitTestStartupThisAP ( >=20 > + LocalContext->MpServices, >=20 > + (EFI_AP_PROCEDURE)RunMpServiceSwitchBSPOn= Ap, >=20 > + ApNumber, >=20 > + 0, >=20 > + (VOID *)LocalContext >=20 > + ); >=20 > + >=20 > + if (ApNumber =3D=3D LocalContext->BspNumber) { >=20 > + UT_ASSERT_STATUS_EQUAL (Status, EFI_INVALID_PARAMETER); >=20 > + } else { >=20 > + UT_ASSERT_NOT_EFI_ERROR (Status); >=20 > + UT_ASSERT_STATUS_EQUAL (LocalContext->ApProcedureReturnStatus, EFI= _DEVICE_ERROR); >=20 > + } >=20 > + } >=20 > + >=20 > + return UNIT_TEST_PASSED; >=20 > +} >=20 > + >=20 > +/** >=20 > + Unit test of MP service SwitchBSP. >=20 > + When switch a disabled AP to be BSP, the return status should be EFI_I= NVALID_PARAMETER. >=20 > + >=20 > + @param[in] Context Context pointer for this test. >=20 > + >=20 > + @retval UNIT_TEST_PASSED The Unit test has completed and = the test >=20 > + case was successful. >=20 > + @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed= . >=20 > +**/ >=20 > +UNIT_TEST_STATUS >=20 > +EFIAPI >=20 > +TestSwitchBSP3 ( >=20 > + IN UNIT_TEST_CONTEXT Context >=20 > + ) >=20 > +{ >=20 > + EFI_STATUS Status; >=20 > + UINTN NewBspNumber; >=20 > + MP_SERVICE_UT_CONTEXT *LocalContext; >=20 > + >=20 > + LocalContext =3D (MP_SERVICE_UT_CONTEXT *)Context; >=20 > + >=20 > + for (NewBspNumber =3D 0; NewBspNumber < LocalContext->NumberOfProcesso= rs; NewBspNumber++) { >=20 > + Status =3D MpServicesUnitTestEnableDisableAP ( >=20 > + LocalContext->MpServices, >=20 > + NewBspNumber, >=20 > + FALSE, >=20 > + NULL >=20 > + ); >=20 > + >=20 > + if (NewBspNumber =3D=3D LocalContext->BspNumber) { >=20 > + UT_ASSERT_STATUS_EQUAL (Status, EFI_INVALID_PARAMETER); >=20 > + } else { >=20 > + UT_ASSERT_NOT_EFI_ERROR (Status); >=20 > + >=20 > + Status =3D MpServicesUnitTestSwitchBSP ( >=20 > + LocalContext->MpServices, >=20 > + NewBspNumber, >=20 > + TRUE >=20 > + ); >=20 > + UT_ASSERT_STATUS_EQUAL (Status, EFI_INVALID_PARAMETER); >=20 > + >=20 > + Status =3D MpServicesUnitTestEnableDisableAP ( >=20 > + LocalContext->MpServices, >=20 > + NewBspNumber, >=20 > + TRUE, >=20 > + NULL >=20 > + ); >=20 > + UT_ASSERT_NOT_EFI_ERROR (Status); >=20 > + } >=20 > + } >=20 > + >=20 > + return UNIT_TEST_PASSED; >=20 > +} >=20 > + >=20 > +/** >=20 > + Unit test of MP service SwitchBSP. >=20 > + When SwitchBSP and EnableOldBSP is TRUE, the new BSP should be in the = enabled state and the old BSP should >=20 > + be in the enabled state. >=20 > + When SwitchBSP and EnableOldBSP is False, the new BSP should be in the= enabled state and the old BSP should >=20 > + be in the disabled state. >=20 > + >=20 > + @param[in] Context Context pointer for this test. >=20 > + >=20 > + @retval UNIT_TEST_PASSED The Unit test has completed and = the test >=20 > + case was successful. >=20 > + @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed= . >=20 > +**/ >=20 > +UNIT_TEST_STATUS >=20 > +EFIAPI >=20 > +TestSwitchBSP4 ( >=20 > + IN UNIT_TEST_CONTEXT Context >=20 > + ) >=20 > +{ >=20 > + EFI_STATUS Status; >=20 > + UINTN NewBspNumber; >=20 > + EFI_PROCESSOR_INFORMATION ProcessorInfoBuffer; >=20 > + MP_SERVICE_UT_CONTEXT *LocalContext; >=20 > + >=20 > + LocalContext =3D (MP_SERVICE_UT_CONTEXT *)Context; >=20 > + >=20 > + for (NewBspNumber =3D 0; NewBspNumber < LocalContext->NumberOfProcesso= rs; NewBspNumber++) { >=20 > + Status =3D MpServicesUnitTestSwitchBSP ( >=20 > + LocalContext->MpServices, >=20 > + NewBspNumber, >=20 > + FALSE >=20 > + ); >=20 > + >=20 > + if (NewBspNumber =3D=3D LocalContext->BspNumber) { >=20 > + UT_ASSERT_STATUS_EQUAL (Status, EFI_INVALID_PARAMETER); >=20 > + } else { >=20 > + UT_ASSERT_NOT_EFI_ERROR (Status); >=20 > + >=20 > + Status =3D MpServicesUnitTestGetProcessorInfo ( >=20 > + LocalContext->MpServices, >=20 > + NewBspNumber, >=20 > + &ProcessorInfoBuffer >=20 > + ); >=20 > + UT_ASSERT_NOT_EFI_ERROR (Status); >=20 > + UT_ASSERT_TRUE ( >=20 > + (ProcessorInfoBuffer.StatusFlag & PROCESSOR_AS_BSP_BIT) && >=20 > + (ProcessorInfoBuffer.StatusFlag & PROCESSOR_ENABLED_BIT) >=20 > + ); >=20 > + >=20 > + Status =3D MpServicesUnitTestGetProcessorInfo ( >=20 > + LocalContext->MpServices, >=20 > + LocalContext->BspNumber, >=20 > + &ProcessorInfoBuffer >=20 > + ); >=20 > + UT_ASSERT_NOT_EFI_ERROR (Status); >=20 > + UT_ASSERT_TRUE ( >=20 > + !(ProcessorInfoBuffer.StatusFlag & PROCESSOR_AS_BSP_BIT) && >=20 > + !(ProcessorInfoBuffer.StatusFlag & PROCESSOR_ENABLED_BIT) >=20 > + ); >=20 > + >=20 > + Status =3D MpServicesUnitTestEnableDisableAP ( >=20 > + LocalContext->MpServices, >=20 > + LocalContext->BspNumber, >=20 > + TRUE, >=20 > + NULL >=20 > + ); >=20 > + UT_ASSERT_NOT_EFI_ERROR (Status); >=20 > + >=20 > + Status =3D MpServicesUnitTestSwitchBSP ( >=20 > + LocalContext->MpServices, >=20 > + LocalContext->BspNumber, >=20 > + TRUE >=20 > + ); >=20 > + UT_ASSERT_NOT_EFI_ERROR (Status); >=20 > + >=20 > + Status =3D MpServicesUnitTestGetProcessorInfo ( >=20 > + LocalContext->MpServices, >=20 > + LocalContext->BspNumber, >=20 > + &ProcessorInfoBuffer >=20 > + ); >=20 > + UT_ASSERT_NOT_EFI_ERROR (Status); >=20 > + UT_ASSERT_TRUE ( >=20 > + (ProcessorInfoBuffer.StatusFlag & PROCESSOR_AS_BSP_BIT) && >=20 > + (ProcessorInfoBuffer.StatusFlag & PROCESSOR_ENABLED_BIT) >=20 > + ); >=20 > + >=20 > + Status =3D MpServicesUnitTestGetProcessorInfo ( >=20 > + LocalContext->MpServices, >=20 > + NewBspNumber, >=20 > + &ProcessorInfoBuffer >=20 > + ); >=20 > + UT_ASSERT_NOT_EFI_ERROR (Status); >=20 > + UT_ASSERT_TRUE ( >=20 > + !(ProcessorInfoBuffer.StatusFlag & PROCESSOR_AS_BSP_BIT) && >=20 > + (ProcessorInfoBuffer.StatusFlag & PROCESSOR_ENABLED_BIT) >=20 > + ); >=20 > + } >=20 > + } >=20 > + >=20 > + return UNIT_TEST_PASSED; >=20 > +} >=20 > + >=20 > +/** >=20 > + Create test suite and unit tests for both EdkiiPeiMpServices2Ppi and E= fiMpServiceProtocol. >=20 > + >=20 > + @param[in] Framework A pointer to the framework that is being per= sisted. >=20 > + @param[in] Context A pointer to the private data buffer. >=20 > + >=20 > + @retval EFI_SUCCESS Create test suite and unit tests successfull= y. >=20 > + @retval Others Create test suite and unit tests unsuccessfu= lly. >=20 > +**/ >=20 > +EFI_STATUS >=20 > +AddCommonTestCase ( >=20 > + IN UNIT_TEST_FRAMEWORK_HANDLE Framework, >=20 > + IN MP_SERVICE_UT_CONTEXT *Context >=20 > + ) >=20 > +{ >=20 > + EFI_STATUS Status; >=20 > + UNIT_TEST_SUITE_HANDLE MpServiceWhoAmITestSuite; >=20 > + UNIT_TEST_SUITE_HANDLE MpServiceGetNumberOfProcessorsTestSuite; >=20 > + UNIT_TEST_SUITE_HANDLE MpServiceGetProcessorInfoTestSuite; >=20 > + UNIT_TEST_SUITE_HANDLE MpServiceEnableDisableAPTestSuite; >=20 > + UNIT_TEST_SUITE_HANDLE MpServiceStartupThisAPTestSuite; >=20 > + UNIT_TEST_SUITE_HANDLE MpServiceStartupAllAPsTestSuite; >=20 > + UNIT_TEST_SUITE_HANDLE MpServiceSwitchBSPTestSuite; >=20 > + >=20 > + MpServiceWhoAmITestSuite =3D NULL; >=20 > + MpServiceGetNumberOfProcessorsTestSuite =3D NULL; >=20 > + MpServiceGetProcessorInfoTestSuite =3D NULL; >=20 > + MpServiceEnableDisableAPTestSuite =3D NULL; >=20 > + MpServiceStartupThisAPTestSuite =3D NULL; >=20 > + MpServiceStartupAllAPsTestSuite =3D NULL; >=20 > + MpServiceSwitchBSPTestSuite =3D NULL; >=20 > + >=20 > + // >=20 > + // Test WhoAmI function >=20 > + // >=20 > + Status =3D CreateUnitTestSuite (&MpServiceWhoAmITestSuite, Framework, = "Identify the currently executing processor", > "MpServices.WhoAmI", NULL, NULL); >=20 > + if (EFI_ERROR (Status)) { >=20 > + DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for MpServiceWho= AmI Test Suite\n")); >=20 > + return Status; >=20 > + } >=20 > + >=20 > + AddTestCase (MpServiceWhoAmITestSuite, "Test WhoAmI 1", "TestWhoAmI1",= TestWhoAmI1, InitUTContext, > CheckUTContext, Context); >=20 > + >=20 > + // >=20 > + // Test GetNumberOfProcessors function >=20 > + // >=20 > + Status =3D CreateUnitTestSuite (&MpServiceGetNumberOfProcessorsTestSui= te, Framework, "Retrieve the number of > logical processor", "MpServices.GetNumberOfProcessors", NULL, NULL); >=20 > + if (EFI_ERROR (Status)) { >=20 > + DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for MpServiceGet= NumberOfProcessors Test Suite\n")); >=20 > + return Status; >=20 > + } >=20 > + >=20 > + AddTestCase (MpServiceGetNumberOfProcessorsTestSuite, "Test GetNumberO= fProcessors 1", > "TestGetNumberOfProcessors1", TestGetNumberOfProcessors1, InitUTContext, = CheckUTContext, Context); >=20 > + AddTestCase (MpServiceGetNumberOfProcessorsTestSuite, "Test GetNumberO= fProcessors 2", > "TestGetNumberOfProcessors2", TestGetNumberOfProcessors2, InitUTContext, = CheckUTContext, Context); >=20 > + AddTestCase (MpServiceGetNumberOfProcessorsTestSuite, "Test GetNumberO= fProcessors 3", > "TestGetNumberOfProcessors3", TestGetNumberOfProcessors3, InitUTContext, = CheckUTContext, Context); >=20 > + >=20 > + // >=20 > + // Test GetProcessorInfo function >=20 > + // >=20 > + Status =3D CreateUnitTestSuite (&MpServiceGetProcessorInfoTestSuite, F= ramework, "Get detailed information on the > requested logical processor", "MpServices.GetProcessorInfo", NULL, NULL); >=20 > + if (EFI_ERROR (Status)) { >=20 > + DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for MpServiceGet= ProcessorInfo Test Suite\n")); >=20 > + return Status; >=20 > + } >=20 > + >=20 > + AddTestCase (MpServiceGetProcessorInfoTestSuite, "Test GetProcessorInf= o 1", "TestGetProcessorInfo1", > TestGetProcessorInfo1, InitUTContext, CheckUTContext, Context); >=20 > + AddTestCase (MpServiceGetProcessorInfoTestSuite, "Test GetProcessorInf= o 2", "TestGetProcessorInfo2", > TestGetProcessorInfo2, InitUTContext, CheckUTContext, Context); >=20 > + >=20 > + // >=20 > + // Test EnableDisableAP function >=20 > + // >=20 > + Status =3D CreateUnitTestSuite (&MpServiceEnableDisableAPTestSuite, Fr= amework, "Caller enables or disables an AP from > this point onward", "MpServices.EnableDisableAP", NULL, NULL); >=20 > + if (EFI_ERROR (Status)) { >=20 > + DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for MpServiceEna= bleDisableAP Test Suite\n")); >=20 > + return Status; >=20 > + } >=20 > + >=20 > + AddTestCase (MpServiceEnableDisableAPTestSuite, "Test EnableDisableAP = 1", "TestEnableDisableAP1", > TestEnableDisableAP1, InitUTContext, CheckUTContext, Context); >=20 > + AddTestCase (MpServiceEnableDisableAPTestSuite, "Test EnableDisableAP = 2", "TestEnableDisableAP2", > TestEnableDisableAP2, InitUTContext, CheckUTContext, Context); >=20 > + AddTestCase (MpServiceEnableDisableAPTestSuite, "Test EnableDisableAP = 3", "TestEnableDisableAP3", > TestEnableDisableAP3, InitUTContext, CheckUTContext, Context); >=20 > + >=20 > + // >=20 > + // Test StartupThisAP function >=20 > + // >=20 > + Status =3D CreateUnitTestSuite (&MpServiceStartupThisAPTestSuite, Fram= ework, "Get the requested AP to execute a > caller-provided function", "MpServices.StartupThisAP", NULL, NULL); >=20 > + if (EFI_ERROR (Status)) { >=20 > + DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for MpServiceSta= rtupThisAP Test Suite\n")); >=20 > + return Status; >=20 > + } >=20 > + >=20 > + AddTestCase (MpServiceStartupThisAPTestSuite, "Test StartupThisAP 1", = "TestStartupThisAP1", TestStartupThisAP1, > InitUTContext, CheckUTContext, Context); >=20 > + AddTestCase (MpServiceStartupThisAPTestSuite, "Test StartupThisAP 2", = "TestStartupThisAP2", TestStartupThisAP2, > InitUTContext, CheckUTContext, Context); >=20 > + AddTestCase (MpServiceStartupThisAPTestSuite, "Test StartupThisAP 3", = "TestStartupThisAP3", TestStartupThisAP3, > InitUTContext, CheckUTContext, Context); >=20 > + AddTestCase (MpServiceStartupThisAPTestSuite, "Test StartupThisAP 4", = "TestStartupThisAP4", TestStartupThisAP4, > InitUTContext, CheckUTContext, Context); >=20 > + >=20 > + // >=20 > + // Test StartupAllAPs function >=20 > + // >=20 > + Status =3D CreateUnitTestSuite (&MpServiceStartupAllAPsTestSuite, Fram= ework, "Execute a caller provided function on all > enabled APs", "MpServices.StartupAllAPs", NULL, NULL); >=20 > + if (EFI_ERROR (Status)) { >=20 > + DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for MpServiceSta= rtupAllAPs Test Suite\n")); >=20 > + return Status; >=20 > + } >=20 > + >=20 > + AddTestCase (MpServiceStartupAllAPsTestSuite, "Test StartupAllAPs 1", = "TestStartupAllAPs1", TestStartupAllAPs1, > InitUTContext, CheckUTContext, Context); >=20 > + AddTestCase (MpServiceStartupAllAPsTestSuite, "Test StartupAllAPs 2", = "TestStartupAllAPs2", TestStartupAllAPs2, > InitUTContext, CheckUTContext, Context); >=20 > + AddTestCase (MpServiceStartupAllAPsTestSuite, "Test StartupAllAPs 3", = "TestStartupAllAPs3", TestStartupAllAPs3, > InitUTContext, CheckUTContext, Context); >=20 > + AddTestCase (MpServiceStartupAllAPsTestSuite, "Test StartupAllAPs 4", = "TestStartupAllAPs4", TestStartupAllAPs4, > InitUTContext, CheckUTContext, Context); >=20 > + AddTestCase (MpServiceStartupAllAPsTestSuite, "Test StartupAllAPs 5", = "TestStartupAllAPs5", TestStartupAllAPs5, > InitUTContext, CheckUTContext, Context); >=20 > + >=20 > + // >=20 > + // Test SwitchBSP function >=20 > + // >=20 > + Status =3D CreateUnitTestSuite (&MpServiceSwitchBSPTestSuite, Framewor= k, "Switch the requested AP to be the BSP > from that point onward", "MpServices.SwitchBSP", NULL, NULL); >=20 > + if (EFI_ERROR (Status)) { >=20 > + DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for MpServiceSwi= tchBSP Test Suite\n")); >=20 > + return Status; >=20 > + } >=20 > + >=20 > + AddTestCase (MpServiceSwitchBSPTestSuite, "Test SwitchBSP 1", "TestSwi= tchBSP1", TestSwitchBSP1, InitUTContext, > CheckUTContext, Context); >=20 > + AddTestCase (MpServiceSwitchBSPTestSuite, "Test SwitchBSP 2", "TestSwi= tchBSP2", TestSwitchBSP2, InitUTContext, > CheckUTContext, Context); >=20 > + AddTestCase (MpServiceSwitchBSPTestSuite, "Test SwitchBSP 3", "TestSwi= tchBSP3", TestSwitchBSP3, InitUTContext, > CheckUTContext, Context); >=20 > + AddTestCase (MpServiceSwitchBSPTestSuite, "Test SwitchBSP 4", "TestSwi= tchBSP4", TestSwitchBSP4, InitUTContext, > FreeUTContext, Context); >=20 > + >=20 > + return EFI_SUCCESS; >=20 > +} >=20 > diff --git a/UefiCpuPkg/Test/UnitTest/EfiMpServicesPpiProtocol/EdkiiPeiMp= Services2PpiPeiUnitTest.inf > b/UefiCpuPkg/Test/UnitTest/EfiMpServicesPpiProtocol/EdkiiPeiMpServices2Pp= iPeiUnitTest.inf > new file mode 100644 > index 0000000000..0b2ddc5585 > --- /dev/null > +++ b/UefiCpuPkg/Test/UnitTest/EfiMpServicesPpiProtocol/EdkiiPeiMpService= s2PpiPeiUnitTest.inf > @@ -0,0 +1,46 @@ > +## @file >=20 > +# PEIM that unit tests the EdkiiPeiMpServices2Ppi >=20 > +# >=20 > +# Copyright (c) 2022, Intel Corporation. All rights reserved.
>=20 > +# SPDX-License-Identifier: BSD-2-Clause-Patent >=20 > +# >=20 > +## >=20 > + >=20 > +[Defines] >=20 > + INF_VERSION =3D 0x00010005 >=20 > + BASE_NAME =3D EdkiiPeiMpServices2PpiPeiUnitTest >=20 > + FILE_GUID =3D A4914810-4D1E-445E-BD6F-F6821B852B5D >=20 > + MODULE_TYPE =3D PEIM >=20 > + VERSION_STRING =3D 1.0 >=20 > + ENTRY_POINT =3D PeiEntryPoint >=20 > + >=20 > +# >=20 > +# The following information is for reference only and not required by th= e build tools. >=20 > +# >=20 > +# VALID_ARCHITECTURES =3D IA32 X64 >=20 > +# >=20 > + >=20 > +[Sources] >=20 > + EfiMpServicesUnitTestCommom.c >=20 > + EfiMpServicesUnitTestCommom.h >=20 > + EdkiiPeiMpServices2PpiUnitTest.c >=20 > + >=20 > +[Packages] >=20 > + MdePkg/MdePkg.dec >=20 > + UefiCpuPkg/UefiCpuPkg.dec >=20 > + >=20 > +[LibraryClasses] >=20 > + BaseLib >=20 > + DebugLib >=20 > + BaseMemoryLib >=20 > + MemoryAllocationLib >=20 > + PeimEntryPoint >=20 > + PeiServicesLib >=20 > + UnitTestPersistenceLib >=20 > + UnitTestLib >=20 > + >=20 > +[Ppis] >=20 > + gEdkiiPeiMpServices2PpiGuid ## CONSUMES >=20 > + >=20 > +[Depex] >=20 > + gEdkiiPeiMpServices2PpiGuid >=20 > diff --git a/UefiCpuPkg/Test/UnitTest/EfiMpServicesPpiProtocol/EfiMpServi= ceProtocolDxeUnitTest.inf > b/UefiCpuPkg/Test/UnitTest/EfiMpServicesPpiProtocol/EfiMpServiceProtocolD= xeUnitTest.inf > new file mode 100644 > index 0000000000..1389092c06 > --- /dev/null > +++ b/UefiCpuPkg/Test/UnitTest/EfiMpServicesPpiProtocol/EfiMpServiceProto= colDxeUnitTest.inf > @@ -0,0 +1,46 @@ > +## @file >=20 > +# DXE driver that unit tests the EfiMpServiceProtocol >=20 > +# >=20 > +# Copyright (c) 2022, Intel Corporation. All rights reserved.
>=20 > +# SPDX-License-Identifier: BSD-2-Clause-Patent >=20 > +# >=20 > +## >=20 > + >=20 > +[Defines] >=20 > + INF_VERSION =3D 0x00010005 >=20 > + BASE_NAME =3D EfiMpServiceProtocolDxeUnitTest >=20 > + FILE_GUID =3D F1E468E2-A32D-4574-895D-6D82B27B08BC >=20 > + MODULE_TYPE =3D DXE_DRIVER >=20 > + VERSION_STRING =3D 1.0 >=20 > + ENTRY_POINT =3D DxeEntryPoint >=20 > + >=20 > +# >=20 > +# The following information is for reference only and not required by th= e build tools. >=20 > +# >=20 > +# VALID_ARCHITECTURES =3D IA32 X64 >=20 > +# >=20 > + >=20 > +[Sources] >=20 > + EfiMpServicesUnitTestCommom.c >=20 > + EfiMpServicesUnitTestCommom.h >=20 > + EfiMpServiceProtocolUnitTest.c >=20 > + >=20 > +[Packages] >=20 > + MdePkg/MdePkg.dec >=20 > + UefiCpuPkg/UefiCpuPkg.dec >=20 > + >=20 > +[LibraryClasses] >=20 > + BaseLib >=20 > + DebugLib >=20 > + BaseMemoryLib >=20 > + MemoryAllocationLib >=20 > + UefiDriverEntryPoint >=20 > + UefiBootServicesTableLib >=20 > + UnitTestPersistenceLib >=20 > + UnitTestLib >=20 > + >=20 > +[Protocols] >=20 > + gEfiMpServiceProtocolGuid ## CONSUMES >=20 > + >=20 > +[Depex] >=20 > + gEfiMpServiceProtocolGuid >=20 > diff --git a/UefiCpuPkg/Test/UnitTest/EfiMpServicesPpiProtocol/EfiMpServi= cesUnitTestCommom.h > b/UefiCpuPkg/Test/UnitTest/EfiMpServicesPpiProtocol/EfiMpServicesUnitTest= Commom.h > new file mode 100644 > index 0000000000..abbbd2faba > --- /dev/null > +++ b/UefiCpuPkg/Test/UnitTest/EfiMpServicesPpiProtocol/EfiMpServicesUnit= TestCommom.h > @@ -0,0 +1,627 @@ > +/** @file >=20 > + Common header file for EfiMpServiceProtocolUnitTest DXE driver. >=20 > + >=20 > + Copyright (c) 2022, Intel Corporation. All rights reserved.
>=20 > + >=20 > + SPDX-License-Identifier: BSD-2-Clause-Patent >=20 > + >=20 > +**/ >=20 > + >=20 > +#ifndef EFI_MP_SERVICES_UNIT_TEST_COMMOM_H_ >=20 > +#define EFI_MP_SERVICES_UNIT_TEST_COMMOM_H_ >=20 > + >=20 > +#include >=20 > +#include >=20 > +#include >=20 > +#include >=20 > +#include >=20 > +#include >=20 > +#include >=20 > +#include >=20 > +#include >=20 > + >=20 > +#define RUN_PROCEDURE_TIMEOUT_VALUE 100000 // microseconds >=20 > + >=20 > +typedef union { >=20 > + EDKII_PEI_MP_SERVICES2_PPI *Ppi; >=20 > + EFI_MP_SERVICES_PROTOCOL *Protocol; >=20 > +} MP_SERVICES; >=20 > + >=20 > +typedef struct { >=20 > + MP_SERVICES MpServices; >=20 > + UINTN BspNumber; >=20 > + UINTN ApNumber; >=20 > + UINTN NumberOfProcessors; >=20 > + UINTN NumberOfEnabledProcessors; >=20 > + UINTN *CommonBuffer; >=20 > + EFI_STATUS ApProcedureReturnStatus; >=20 > + UINTN *DisabledApNumber; >=20 > +} MP_SERVICE_UT_CONTEXT; >=20 > + >=20 > +/** >=20 > + Get EFI_MP_SERVICES_PROTOCOL pointer. >=20 > + >=20 > + @param[out] MpServices Pointer to the buffer where EFI_MP_SERVICES_= PROTOCOL is stored >=20 > + >=20 > + @retval EFI_SUCCESS EFI_MP_SERVICES_PROTOCOL interface is return= ed >=20 > + @retval EFI_NOT_FOUND EFI_MP_SERVICES_PROTOCOL interface is not fo= und >=20 > +**/ >=20 > +EFI_STATUS >=20 > +MpServicesUnitTestGetMpServices ( >=20 > + OUT MP_SERVICES *MpServices >=20 > + ); >=20 > + >=20 > +/** >=20 > + Retrieve the number of logical processor in the platform and the numbe= r of those logical processors that >=20 > + are enabled on this boot. >=20 > + >=20 > + @param[in] MpServices MP_SERVICES structure. >=20 > + @param[out] NumberOfProcessors Pointer to the total number of logical= processors in the system, including >=20 > + the BSP and disabled APs. >=20 > + @param[out] NumberOfEnabledProcessors Pointer to the number of process= ors in the system that are enabled. >=20 > + >=20 > + @retval EFI_SUCCESS Retrieve the number of logical processor suc= cessfully >=20 > + @retval Others Retrieve the number of logical processor uns= uccessfully >=20 > +**/ >=20 > +EFI_STATUS >=20 > +MpServicesUnitTestGetNumberOfProcessors ( >=20 > + IN MP_SERVICES MpServices, >=20 > + OUT UINTN *NumberOfProcessors, >=20 > + OUT UINTN *NumberOfEnabledProcessors >=20 > + ); >=20 > + >=20 > +/** >=20 > + Get detailed information on the requested logical processor. >=20 > + >=20 > + @param[in] MpServices MP_SERVICES structure. >=20 > + @param[in] ProcessorNumber The handle number of the processor. >=20 > + @param[out] ProcessorInfoBuffer Pointer to the buffer where the proces= sor information is stored. >=20 > + >=20 > + @retval EFI_SUCCESS Get information on the requested logical pro= cessor successfully >=20 > + @retval Others Get information on the requested logical pro= cessor unsuccessfully >=20 > +**/ >=20 > +EFI_STATUS >=20 > +MpServicesUnitTestGetProcessorInfo ( >=20 > + IN MP_SERVICES MpServices, >=20 > + IN UINTN ProcessorNumber, >=20 > + OUT EFI_PROCESSOR_INFORMATION *ProcessorInfoBuffer >=20 > + ); >=20 > + >=20 > +/** >=20 > + Execute a caller provided function on all enabled APs. >=20 > + >=20 > + @param[in] MpServices MP_SERVICES structure. >=20 > + @param[in] Procedure Pointer to the function to be run on enabled= APs of the system. >=20 > + @param[in] SingleThread If TRUE, then all the enabled APs execute th= e function specified by Procedure >=20 > + one by one, in ascending order of processor = handle number. >=20 > + If FALSE, then all the enabled APs execute t= he function specified by Procedure >=20 > + simultaneously. >=20 > + @param[in] TimeoutInMicroSeconds Indicates the time limit in microsec= onds for APs to return from Procedure, >=20 > + for blocking mode only. Zero means i= nfinity. >=20 > + @param[in] ProcedureArgument The parameter passed into Procedure = for all APs. >=20 > + >=20 > + @retval EFI_SUCCESS Execute a caller provided function on all en= abled APs successfully >=20 > + @retval Others Execute a caller provided function on all en= abled APs unsuccessfully >=20 > +**/ >=20 > +EFI_STATUS >=20 > +MpServicesUnitTestStartupAllAPs ( >=20 > + IN MP_SERVICES MpServices, >=20 > + IN EFI_AP_PROCEDURE Procedure, >=20 > + IN BOOLEAN SingleThread, >=20 > + IN UINTN TimeoutInMicroSeconds, >=20 > + IN VOID *ProcedureArgument >=20 > + ); >=20 > + >=20 > +/** >=20 > + Caller gets one enabled AP to execute a caller-provided function. >=20 > + >=20 > + @param[in] MpServices MP_SERVICES structure. >=20 > + @param[in] Procedure Pointer to the function to be run on enabled= APs of the system. >=20 > + @param[in] ProcessorNumber The handle number of the AP. >=20 > + @param[in] TimeoutInMicroSeconds Indicates the time limit in microsec= onds for APs to return from Procedure, >=20 > + for blocking mode only. Zero means i= nfinity. >=20 > + @param[in] ProcedureArgument The parameter passed into Procedure = for all APs. >=20 > + >=20 > + @retval EFI_SUCCESS Caller gets one enabled AP to execute a call= er-provided function successfully >=20 > + @retval Others Caller gets one enabled AP to execute a call= er-provided function unsuccessfully >=20 > +**/ >=20 > +EFI_STATUS >=20 > +MpServicesUnitTestStartupThisAP ( >=20 > + IN MP_SERVICES MpServices, >=20 > + IN EFI_AP_PROCEDURE Procedure, >=20 > + IN UINTN ProcessorNumber, >=20 > + IN UINTN TimeoutInMicroSeconds, >=20 > + IN VOID *ProcedureArgument >=20 > + ); >=20 > + >=20 > +/** >=20 > + Switch the requested AP to be the BSP from that point onward. >=20 > + >=20 > + @param[in] MpServices MP_SERVICES structure. >=20 > + @param[in] ProcessorNumber The handle number of AP that is to become = the new BSP. >=20 > + @param[in] EnableOldBSP If TRUE, the old BSP will be listed as an en= abled AP. Otherwise, it will be disabled. >=20 > + >=20 > + @retval EFI_SUCCESS Switch the requested AP to be the BSP succes= sfully >=20 > + @retval Others Switch the requested AP to be the BSP unsucc= essfully >=20 > +**/ >=20 > +EFI_STATUS >=20 > +MpServicesUnitTestSwitchBSP ( >=20 > + IN MP_SERVICES MpServices, >=20 > + IN UINTN ProcessorNumber, >=20 > + IN BOOLEAN EnableOldBSP >=20 > + ); >=20 > + >=20 > +/** >=20 > + Caller enables or disables an AP from this point onward. >=20 > + >=20 > + @param[in] MpServices MP_SERVICES structure. >=20 > + @param[in] ProcessorNumber The handle number of the AP. >=20 > + @param[in] EnableAP Specifies the new state for the processor fo= r enabled, FALSE for disabled. >=20 > + @param[in] HealthFlag If not NULL, a pointer to a value that speci= fies the new health status of the AP. >=20 > + >=20 > + @retval EFI_SUCCESS Caller enables or disables an AP successfull= y. >=20 > + @retval Others Caller enables or disables an AP unsuccessfu= lly. >=20 > +**/ >=20 > +EFI_STATUS >=20 > +MpServicesUnitTestEnableDisableAP ( >=20 > + IN MP_SERVICES MpServices, >=20 > + IN UINTN ProcessorNumber, >=20 > + IN BOOLEAN EnableAP, >=20 > + IN UINT32 *HealthFlag >=20 > + ); >=20 > + >=20 > +/** >=20 > + Get the handle number for the calling processor. >=20 > + >=20 > + @param[in] MpServices MP_SERVICES structure. >=20 > + @param[out] ProcessorNumber The handle number for the calling processo= r. >=20 > + >=20 > + @retval EFI_SUCCESS Get the handle number for the calling proces= sor successfully. >=20 > + @retval Others Get the handle number for the calling proces= sor unsuccessfully. >=20 > +**/ >=20 > +EFI_STATUS >=20 > +MpServicesUnitTestWhoAmI ( >=20 > + IN MP_SERVICES MpServices, >=20 > + OUT UINTN *ProcessorNumber >=20 > + ); >=20 > + >=20 > +/** >=20 > + Empty procedure to be run on specified CPU. >=20 > + >=20 > + @param[in,out] Buffer The pointer to private data buffer. >=20 > +**/ >=20 > +VOID >=20 > +EmptyProcedure ( >=20 > + IN OUT VOID *Buffer >=20 > + ); >=20 > + >=20 > +/** >=20 > + Produce to store ProcessorNumber in CommonBuffer and be run on specifi= ed CPU. >=20 > + >=20 > + @param[in,out] Buffer The pointer to private data buffer. >=20 > +**/ >=20 > +VOID >=20 > +StoreCpuNumbers ( >=20 > + IN OUT VOID *Buffer >=20 > + ); >=20 > + >=20 > +/** >=20 > + Prep routine for Unit test function. >=20 > + To save the ProcessorNumber of disabled AP and temporarily enable it. >=20 > + >=20 > + @param[in] Context Context pointer for this test. >=20 > + >=20 > + @retval UNIT_TEST_PASSED Prep routine runs successful. >=20 > + @retval UNIT_TEST_ERROR_TEST_FAILED Prep routine runs unsuccessful. >=20 > +**/ >=20 > +UNIT_TEST_STATUS >=20 > +EFIAPI >=20 > +InitUTContext ( >=20 > + IN UNIT_TEST_CONTEXT Context >=20 > + ); >=20 > + >=20 > +/** >=20 > + Cleanup routine for Unit test function. >=20 > + If any processor is disabled unexpectedly then reenable it. >=20 > + >=20 > + @param[in] Context Context pointer for this test. >=20 > +**/ >=20 > +VOID >=20 > +EFIAPI >=20 > +CheckUTContext ( >=20 > + IN UNIT_TEST_CONTEXT Context >=20 > + ); >=20 > + >=20 > +/** >=20 > + Cleanup routine for Unit test function. >=20 > + It will be called by the last "AddTestCase" to restore AP state and fr= ee pointer. >=20 > + >=20 > + @param[in] Context Context pointer for this test. >=20 > +**/ >=20 > +VOID >=20 > +EFIAPI >=20 > +FreeUTContext ( >=20 > + IN UNIT_TEST_CONTEXT Context >=20 > + ); >=20 > + >=20 > +/** >=20 > + Unit test of MP service WhoAmI. >=20 > + The range of ProcessorNumber should be from 0 to NumberOfCPUs minus 1. >=20 > + The ProcessorNumbers of all CPUs are unique. >=20 > + >=20 > + @param[in] Context Context pointer for this test. >=20 > + >=20 > + @retval UNIT_TEST_PASSED The Unit test has completed and = the test >=20 > + case was successful. >=20 > + @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed= . >=20 > +**/ >=20 > +UNIT_TEST_STATUS >=20 > +EFIAPI >=20 > +TestWhoAmI1 ( >=20 > + IN UNIT_TEST_CONTEXT Context >=20 > + ); >=20 > + >=20 > +/** >=20 > + Unit test of MP service GetNumberOfProcessors. >=20 > + NumberOfProcessors should be greater that 0 and not less than NumberOf= EnabledProcessors. >=20 > + >=20 > + @param[in] Context Context pointer for this test. >=20 > + >=20 > + @retval UNIT_TEST_PASSED The Unit test has completed and = the test >=20 > + case was successful. >=20 > + @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed= . >=20 > +**/ >=20 > +UNIT_TEST_STATUS >=20 > +EFIAPI >=20 > +TestGetNumberOfProcessors1 ( >=20 > + IN UNIT_TEST_CONTEXT Context >=20 > + ); >=20 > + >=20 > +/** >=20 > + Unit test of MP service GetNumberOfProcessors. >=20 > + When this service is called from an AP, the return status should be EF= I_DEVICE_ERROR. >=20 > + >=20 > + @param[in] Context Context pointer for this test. >=20 > + >=20 > + @retval UNIT_TEST_PASSED The Unit test has completed and = the test >=20 > + case was successful. >=20 > + @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed= . >=20 > +**/ >=20 > +UNIT_TEST_STATUS >=20 > +EFIAPI >=20 > +TestGetNumberOfProcessors2 ( >=20 > + IN UNIT_TEST_CONTEXT Context >=20 > + ); >=20 > + >=20 > +/** >=20 > + Unit test of MP service GetNumberOfProcessors. >=20 > + Call EnableDisableAP() to change the number of enabled AP. >=20 > + >=20 > + @param[in] Context Context pointer for this test. >=20 > + >=20 > + @retval UNIT_TEST_PASSED The Unit test has completed and = the test >=20 > + case was successful. >=20 > + @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed= . >=20 > +**/ >=20 > +UNIT_TEST_STATUS >=20 > +EFIAPI >=20 > +TestGetNumberOfProcessors3 ( >=20 > + IN UNIT_TEST_CONTEXT Context >=20 > + ); >=20 > + >=20 > +/** >=20 > + Unit test of MP service GetProcessorInfo. >=20 > + When all the parameters are valid, all reserved bits of StatusFlag in = ProcessorInfoBuffer should be set to zero. >=20 > + When all the parameters are valid, the StatusFlag should not have an i= nvalid value (The BSP can never be in the disabled > state.). >=20 > + When called with nonexistent processor handle, the return status shoul= d be EFI_NOT_FOUND. >=20 > + >=20 > + @param[in] Context Context pointer for this test. >=20 > + >=20 > + @retval UNIT_TEST_PASSED The Unit test has completed and = the test >=20 > + case was successful. >=20 > + @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed= . >=20 > +**/ >=20 > +UNIT_TEST_STATUS >=20 > +EFIAPI >=20 > +TestGetProcessorInfo1 ( >=20 > + IN UNIT_TEST_CONTEXT Context >=20 > + ); >=20 > + >=20 > +/** >=20 > + Unit test of MP service GetProcessorInfo. >=20 > + When this service is called from an AP, the return status should be EF= I_DEVICE_ERROR. >=20 > + >=20 > + @param[in] Context Context pointer for this test. >=20 > + >=20 > + @retval UNIT_TEST_PASSED The Unit test has completed and = the test >=20 > + case was successful. >=20 > + @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed= . >=20 > +**/ >=20 > +UNIT_TEST_STATUS >=20 > +EFIAPI >=20 > +TestGetProcessorInfo2 ( >=20 > + IN UNIT_TEST_CONTEXT Context >=20 > + ); >=20 > + >=20 > +/** >=20 > + Unit test of MP service EnableDisableAP. >=20 > + When called with BSP number, the return status should be EFI_INVALID_P= ARAMETER. >=20 > + When called with a nonexistent processor handle, the return status sho= uld be EFI_NOT_FOUND. >=20 > + The AP should be really Enable/Disabled. >=20 > + >=20 > + @param[in] Context Context pointer for this test. >=20 > + >=20 > + @retval UNIT_TEST_PASSED The Unit test has completed and = the test >=20 > + case was successful. >=20 > + @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed= . >=20 > +**/ >=20 > +UNIT_TEST_STATUS >=20 > +EFIAPI >=20 > +TestEnableDisableAP1 ( >=20 > + IN UNIT_TEST_CONTEXT Context >=20 > + ); >=20 > + >=20 > +/** >=20 > + Unit test of MP service EnableDisableAP. >=20 > + When run this procedure on AP, the return status should be EFI_DEVICE_= ERROR. >=20 > + >=20 > + @param[in] Context Context pointer for this test. >=20 > + >=20 > + @retval UNIT_TEST_PASSED The Unit test has completed and = the test >=20 > + case was successful. >=20 > + @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed= . >=20 > +**/ >=20 > +UNIT_TEST_STATUS >=20 > +EFIAPI >=20 > +TestEnableDisableAP2 ( >=20 > + IN UNIT_TEST_CONTEXT Context >=20 > + ); >=20 > + >=20 > +/** >=20 > + Unit test of MP service EnableDisableAP. >=20 > + When run this procedure on AP, the return status should be EFI_DEVICE_= ERROR. >=20 > + >=20 > + @param[in] Context Context pointer for this test. >=20 > + >=20 > + @retval UNIT_TEST_PASSED The Unit test has completed and = the test >=20 > + case was successful. >=20 > + @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed= . >=20 > +**/ >=20 > +UNIT_TEST_STATUS >=20 > +EFIAPI >=20 > +TestEnableDisableAP3 ( >=20 > + IN UNIT_TEST_CONTEXT Context >=20 > + ); >=20 > + >=20 > +/** >=20 > + Unit test of MP service StartupThisAP. >=20 > + When called to startup a BSP, the return status should be EFI_INVALID_= PARAMETER. >=20 > + When called with a nonexistent processor handle, the return status sho= uld be EFI_NOT_FOUND. >=20 > + The requested AP should execute the Procedure when called by StartupTh= isAP. >=20 > + >=20 > + @param[in] Context Context pointer for this test. >=20 > + >=20 > + @retval UNIT_TEST_PASSED The Unit test has completed and = the test >=20 > + case was successful. >=20 > + @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed= . >=20 > +**/ >=20 > +UNIT_TEST_STATUS >=20 > +EFIAPI >=20 > +TestStartupThisAP1 ( >=20 > + IN UNIT_TEST_CONTEXT Context >=20 > + ); >=20 > + >=20 > +/** >=20 > + Unit test of MP service StartupThisAP. >=20 > + When this service is called from an AP, the return status should be EF= I_DEVICE_ERROR. >=20 > + >=20 > + @param[in] Context Context pointer for this test. >=20 > + >=20 > + @retval UNIT_TEST_PASSED The Unit test has completed and = the test >=20 > + case was successful. >=20 > + @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed= . >=20 > +**/ >=20 > +UNIT_TEST_STATUS >=20 > +EFIAPI >=20 > +TestStartupThisAP2 ( >=20 > + IN UNIT_TEST_CONTEXT Context >=20 > + ); >=20 > + >=20 > +/** >=20 > + Unit test of MP service StartupThisAP. >=20 > + When timeout expired before the requested AP has finished, the return = status should be EFI_TIMEOUT. >=20 > + >=20 > + @param[in] Context Context pointer for this test. >=20 > + >=20 > + @retval UNIT_TEST_PASSED The Unit test has completed and = the test >=20 > + case was successful. >=20 > + @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed= . >=20 > +**/ >=20 > +UNIT_TEST_STATUS >=20 > +EFIAPI >=20 > +TestStartupThisAP3 ( >=20 > + IN UNIT_TEST_CONTEXT Context >=20 > + ); >=20 > + >=20 > +/** >=20 > + Unit test of MP service StartupThisAP. >=20 > + When called with disabled AP, the return status should be EFI_INVALID_= PARAMETER. >=20 > + >=20 > + @param[in] Context Context pointer for this test. >=20 > + >=20 > + @retval UNIT_TEST_PASSED The Unit test has completed and = the test >=20 > + case was successful. >=20 > + @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed= . >=20 > +**/ >=20 > +UNIT_TEST_STATUS >=20 > +EFIAPI >=20 > +TestStartupThisAP4 ( >=20 > + IN UNIT_TEST_CONTEXT Context >=20 > + ); >=20 > + >=20 > +/** >=20 > + Unit test of MP service StartupAllAPs. >=20 > + All APs should execute the Procedure when called by StartupAllAPs. >=20 > + >=20 > + @param[in] Context Context pointer for this test. >=20 > + >=20 > + @retval UNIT_TEST_PASSED The Unit test has completed and = the test >=20 > + case was successful. >=20 > + @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed= . >=20 > +**/ >=20 > +UNIT_TEST_STATUS >=20 > +EFIAPI >=20 > +TestStartupAllAPs1 ( >=20 > + IN UNIT_TEST_CONTEXT Context >=20 > + ); >=20 > + >=20 > +/** >=20 > + Unit test of MP service StartupAllAPs. >=20 > + When called in single thread, the return status should be EFI_SUCCESS = and AP executes in ascending order >=20 > + of processor handle number. >=20 > + >=20 > + @param[in] Context Context pointer for this test. >=20 > + >=20 > + @retval UNIT_TEST_PASSED The Unit test has completed and = the test >=20 > + case was successful. >=20 > + @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed= . >=20 > +**/ >=20 > +UNIT_TEST_STATUS >=20 > +EFIAPI >=20 > +TestStartupAllAPs2 ( >=20 > + IN UNIT_TEST_CONTEXT Context >=20 > + ); >=20 > + >=20 > +/** >=20 > + Unit test of MP service StartupAllAPs. >=20 > + When this service is called from an AP, the return status should be EF= I_DEVICE_ERROR. >=20 > + >=20 > + @param[in] Context Context pointer for this test. >=20 > + >=20 > + @retval UNIT_TEST_PASSED The Unit test has completed and = the test >=20 > + case was successful. >=20 > + @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed= . >=20 > +**/ >=20 > +UNIT_TEST_STATUS >=20 > +EFIAPI >=20 > +TestStartupAllAPs3 ( >=20 > + IN UNIT_TEST_CONTEXT Context >=20 > + ); >=20 > + >=20 > +/** >=20 > + Unit test of MP service StartupAllAPs. >=20 > + When called with all AP timeout, the return status should be EFI_TIMEO= UT. >=20 > + >=20 > + @param[in] Context Context pointer for this test. >=20 > + >=20 > + @retval UNIT_TEST_PASSED The Unit test has completed and = the test >=20 > + case was successful. >=20 > + @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed= . >=20 > +**/ >=20 > +UNIT_TEST_STATUS >=20 > +EFIAPI >=20 > +TestStartupAllAPs4 ( >=20 > + IN UNIT_TEST_CONTEXT Context >=20 > + ); >=20 > + >=20 > +/** >=20 > + Unit test of MP service StartupAllAPs. >=20 > + When called with the empty Procedure on all disabled APs, the return s= tatus should be EFI_NOT_STARTED. >=20 > + >=20 > + @param[in] Context Context pointer for this test. >=20 > + >=20 > + @retval UNIT_TEST_PASSED The Unit test has completed and = the test >=20 > + case was successful. >=20 > + @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed= . >=20 > +**/ >=20 > +UNIT_TEST_STATUS >=20 > +EFIAPI >=20 > +TestStartupAllAPs5 ( >=20 > + IN UNIT_TEST_CONTEXT Context >=20 > + ); >=20 > + >=20 > +/** >=20 > + Unit test of MP service SwitchBSP. >=20 > + When switch current BSP to be BSP, the return status should be EFI_INV= ALID_PARAMETER. >=20 > + When switch nonexistent processor to be BSP, the return status should = be EFI_NOT_FOUND. >=20 > + After switch BSP, all APs(includes new AP) should execute the Procedur= e when called by StartupAllAP. >=20 > + >=20 > + @param[in] Context Context pointer for this test. >=20 > + >=20 > + @retval UNIT_TEST_PASSED The Unit test has completed and = the test >=20 > + case was successful. >=20 > + @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed= . >=20 > +**/ >=20 > +UNIT_TEST_STATUS >=20 > +EFIAPI >=20 > +TestSwitchBSP1 ( >=20 > + IN UNIT_TEST_CONTEXT Context >=20 > + ); >=20 > + >=20 > +/** >=20 > + Unit test of MP service SwitchBSP. >=20 > + When run this procedure on AP, the return status should be EFI_DEVICE_= ERROR. >=20 > + >=20 > + @param[in] Context Context pointer for this test. >=20 > + >=20 > + @retval UNIT_TEST_PASSED The Unit test has completed and = the test >=20 > + case was successful. >=20 > + @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed= . >=20 > +**/ >=20 > +UNIT_TEST_STATUS >=20 > +EFIAPI >=20 > +TestSwitchBSP2 ( >=20 > + IN UNIT_TEST_CONTEXT Context >=20 > + ); >=20 > + >=20 > +/** >=20 > + Unit test of MP service SwitchBSP. >=20 > + When switch a disabled AP to be BSP, the return status should be EFI_I= NVALID_PARAMETER. >=20 > + >=20 > + @param[in] Context Context pointer for this test. >=20 > + >=20 > + @retval UNIT_TEST_PASSED The Unit test has completed and = the test >=20 > + case was successful. >=20 > + @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed= . >=20 > +**/ >=20 > +UNIT_TEST_STATUS >=20 > +EFIAPI >=20 > +TestSwitchBSP3 ( >=20 > + IN UNIT_TEST_CONTEXT Context >=20 > + ); >=20 > + >=20 > +/** >=20 > + Unit test of MP service SwitchBSP. >=20 > + When SwitchBSP and EnableOldBSP is TRUE, the new BSP should be in the = enabled state and the old BSP should >=20 > + be in the enabled state. >=20 > + When SwitchBSP and EnableOldBSP is False, the new BSP should be in the= enabled state and the old BSP should >=20 > + be in the disabled state. >=20 > + >=20 > + @param[in] Context Context pointer for this test. >=20 > + >=20 > + @retval UNIT_TEST_PASSED The Unit test has completed and = the test >=20 > + case was successful. >=20 > + @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed= . >=20 > +**/ >=20 > +UNIT_TEST_STATUS >=20 > +EFIAPI >=20 > +TestSwitchBSP4 ( >=20 > + IN UNIT_TEST_CONTEXT Context >=20 > + ); >=20 > + >=20 > +/** >=20 > + Create test suite and unit tests for both EdkiiPeiMpServices2Ppi and E= fiMpServiceProtocol. >=20 > + >=20 > + @param[in] Framework A pointer to the framework that is being per= sisted. >=20 > + @param[in] Context A pointer to the private data buffer. >=20 > + >=20 > + @retval EFI_SUCCESS Create test suite and unit tests successfull= y. >=20 > + @retval Others Create test suite and unit tests unsuccessfu= lly. >=20 > +**/ >=20 > +EFI_STATUS >=20 > +AddCommonTestCase ( >=20 > + IN UNIT_TEST_FRAMEWORK_HANDLE Framework, >=20 > + IN MP_SERVICE_UT_CONTEXT *Context >=20 > + ); >=20 > + >=20 > +#endif >=20 > diff --git a/UefiCpuPkg/UefiCpuPkg.dsc b/UefiCpuPkg/UefiCpuPkg.dsc > index f694b3a77c..db5fe654b5 100644 > --- a/UefiCpuPkg/UefiCpuPkg.dsc > +++ b/UefiCpuPkg/UefiCpuPkg.dsc > @@ -63,6 +63,9 @@ > MicrocodeLib|UefiCpuPkg/Library/MicrocodeLib/MicrocodeLib.inf >=20 > SmmCpuRendezvousLib|UefiCpuPkg/Library/SmmCpuRendezvousLib/SmmCpuRende= zvousLib.inf >=20 > CpuPageTableLib|UefiCpuPkg/Library/CpuPageTableLib/CpuPageTableLib.inf >=20 > + UnitTestPersistenceLib|UnitTestFrameworkPkg/Library/UnitTestPersistenc= eLibNull/UnitTestPersistenceLibNull.inf >=20 > + UnitTestLib|UnitTestFrameworkPkg/Library/UnitTestLib/UnitTestLib.inf >=20 > + UnitTestResultReportLib|UnitTestFrameworkPkg/Library/UnitTestResultRep= ortLib/UnitTestResultReportLibDebugLib.inf >=20 >=20 >=20 > [LibraryClasses.common.SEC] >=20 > PlatformSecLib|UefiCpuPkg/Library/PlatformSecLibNull/PlatformSecLibNul= l.inf >=20 > @@ -177,6 +180,8 @@ > UefiCpuPkg/ResetVector/Vtf0/Bin/ResetVector.inf >=20 > UefiCpuPkg/Library/SmmCpuRendezvousLib/SmmCpuRendezvousLib.inf >=20 > UefiCpuPkg/Library/CpuPageTableLib/CpuPageTableLib.inf >=20 > + UefiCpuPkg/Test/UnitTest/EfiMpServicesPpiProtocol/EdkiiPeiMpServices2P= piPeiUnitTest.inf >=20 > + UefiCpuPkg/Test/UnitTest/EfiMpServicesPpiProtocol/EfiMpServiceProtocol= DxeUnitTest.inf >=20 >=20 >=20 > [BuildOptions] >=20 > *_*_*_CC_FLAGS =3D -D DISABLE_NEW_DEPRECATED_INTERFACES >=20 > -- > 2.28.0.windows.1