From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) by mx.groups.io with SMTP id smtpd.web09.10159.1611057957715788342 for ; Tue, 19 Jan 2021 04:05:57 -0800 Authentication-Results: mx.groups.io; dkim=pass header.i=@intel.onmicrosoft.com header.s=selector2-intel-onmicrosoft-com header.b=agl+RZpT; spf=pass (domain: intel.com, ip: 192.55.52.93, mailfrom: ray.ni@intel.com) IronPort-SDR: udJ4FplraI9VTv3NrAddGZhvKRkrJ/PL3d1CLKAN8L2ZKv0mmdSVyW7HarZbzlSpGFpBLpGidG gU/4nCjnSgWA== X-IronPort-AV: E=McAfee;i="6000,8403,9868"; a="175412537" X-IronPort-AV: E=Sophos;i="5.79,358,1602572400"; d="scan'208";a="175412537" Received: from fmsmga006.fm.intel.com ([10.253.24.20]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 19 Jan 2021 04:05:56 -0800 IronPort-SDR: 3s9hbrMosU6FOBc4mZkYIot7TMK/BC2K7Zax2mbkiQ6ff1gJ8we3revGhg6pcP0ZezNCYZsUaR EjNKZuugbiUw== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.79,358,1602572400"; d="scan'208";a="570987426" Received: from orsmsx603.amr.corp.intel.com ([10.22.229.16]) by fmsmga006.fm.intel.com with ESMTP; 19 Jan 2021 04:05:56 -0800 Received: from orsmsx608.amr.corp.intel.com (10.22.229.21) by ORSMSX603.amr.corp.intel.com (10.22.229.16) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.1713.5; Tue, 19 Jan 2021 04:05:56 -0800 Received: from orsedg603.ED.cps.intel.com (10.7.248.4) by orsmsx608.amr.corp.intel.com (10.22.229.21) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.1713.5 via Frontend Transport; Tue, 19 Jan 2021 04:05:56 -0800 Received: from NAM12-DM6-obe.outbound.protection.outlook.com (104.47.59.172) by edgegateway.intel.com (134.134.137.100) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.1.1713.5; Tue, 19 Jan 2021 04:05:55 -0800 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=hhDhtXwPkRpkKIlgQ20JwpwKPZIeNDQOMXiek1yQt58rh9NXdq83hFJ6RbpCt4/JazBDlcEPsszXwiuXphIKzAPpg7HKerM3CtzCWRWtMiE1D/pGAlzE6V/1qpWPwOXk7sJDnPJNlt1ceRTR6EsMKeUzHCwz9n1cNd6GZtC8RCSjhytXIt6MCzesNcxZemBx5EoCUPVhSmEkXpW56VOdvDK8lskJp2JW5IaI8a+S+XhCkiDDgokkmcvbfBYG8RLY24lOtKRdhP+01pkbwQAnwA1rePJL7FW01iU0Op60DyOX30ZZoZxCQU4uh4oQo1DY7eme8CZobqgt5qGOh6p8Qw== 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-SenderADCheck; bh=BV4seHR9CrzeW9zg7m58EaF97tNrTzBoa+DM9HPY3G8=; b=Orx56O9buubs7xLWWmxh94GMaTdMzcFshzHcBexEPmw2CnSeeBChe1qFnkrdJiCqzrbjCtW4KTzaNpLc42VgUPFV/hRE6HjhA6H1SsisUWmKlSrSLSmEH1Fyay25XK89JKqyH/JB26g+RTJZOQ0inJ+ACXXy6okXFriHdmtSzuTJzU/JWD6bakmxhNjBXdHRWe4SSiSiJ3gd9rhRZiUtHm4Zpqz5wS6h0O7tgbT4s/YnBfFRh76R13CdfIzO807YbCY8sz5/fkeXUKX3A9v3EdVLCFQFmMB7X6sLhnZjfn5yE7xO7mDai/BtOZb/IoN1J0aj+L5ccdtzNQNxwUS87A== 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 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=intel.onmicrosoft.com; s=selector2-intel-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=BV4seHR9CrzeW9zg7m58EaF97tNrTzBoa+DM9HPY3G8=; b=agl+RZpTxV7r4nu6MDjcIQwJ1QEzLPZ30xNo83EFId9oz/Nbr1uTP1LcYIy7PO03nGQ/g8VtkEjI0zA1IDgmlnz0Uzjf+JYse1tIrSa6rrx7QbERyh6h7ppBznh7S/oJo5UQYWZrb2feBKwK9N7O4qn7TT6JE0j30UgrCbyu+UY= Received: from CO1PR11MB4930.namprd11.prod.outlook.com (2603:10b6:303:9b::11) by CO1PR11MB5010.namprd11.prod.outlook.com (2603:10b6:303:93::9) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3763.10; Tue, 19 Jan 2021 12:05:54 +0000 Received: from CO1PR11MB4930.namprd11.prod.outlook.com ([fe80::d18:1234:c1d6:5936]) by CO1PR11MB4930.namprd11.prod.outlook.com ([fe80::d18:1234:c1d6:5936%7]) with mapi id 15.20.3763.014; Tue, 19 Jan 2021 12:05:54 +0000 From: "Ni, Ray" To: "Lou, Yun" , "devel@edk2.groups.io" CC: "Dong, Eric" , Laszlo Ersek , "Kumar, Rahul1" Subject: Re: [PATCH v7 2/2] UefiCpuPkg/CpuCacheInfoLib: Add new CpuCacheInfoLib. Thread-Topic: [PATCH v7 2/2] UefiCpuPkg/CpuCacheInfoLib: Add new CpuCacheInfoLib. Thread-Index: AQHW7NtUK5OcenHNwU6WjwPtUTSiR6ou3RYw Date: Tue, 19 Jan 2021 12:05:54 +0000 Message-ID: References: <20210117141541.3627-1-yun.lou@intel.com> <20210117141541.3627-2-yun.lou@intel.com> In-Reply-To: <20210117141541.3627-2-yun.lou@intel.com> Accept-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: dlp-version: 11.5.1.3 dlp-reaction: no-action dlp-product: dlpe-windows authentication-results: intel.com; dkim=none (message not signed) header.d=none;intel.com; dmarc=none action=none header.from=intel.com; x-originating-ip: [124.77.195.36] x-ms-publictraffictype: Email x-ms-office365-filtering-correlation-id: 784ec857-eebc-4d90-c75b-08d8bc72929f x-ms-traffictypediagnostic: CO1PR11MB5010: x-ms-exchange-transport-forked: True x-microsoft-antispam-prvs: x-ms-oob-tlc-oobclassifiers: OLM:8882; x-ms-exchange-senderadcheck: 1 x-microsoft-antispam: BCL:0; x-microsoft-antispam-message-info: o1cWAnukbM1v+Pe2yYCqXrJ3CQdK2yPReVzCfaSXiAcqEgxF8/9rir7T5brQMRRoCXEzNCSIDXkudRORA3iAIHDfvK6x3f9kKKIer2vLC2W8tYD8Je1zoyrQgXIBaJuwzWgqnfspvO85hiioEsTMse1lkM42PQqlDRAieOKCzfgWzJhCt0XHlPgb+KFu+6JfJIQztp4FXnjC6sMy1P2YfgY1ArvLmKXFCjochYPwAIw3LFsLafrIT9sWpx+3sqTPJ/UN0+snTTIM6MKb19AJHfDs6T/OG/P6Uf6n5m79nu4Hr7NHpGTQEht1DfVQBhDSxd6pVGPKhX7hXP2EDXq6fEmbzcPL5Ldbdpwlsq1cvUiTgohYvMqM0F825+QHHNpOezcQK1xpG3PMAVQWzOEfK2XLUwkwmSI81x7X1ONpbS8ZFzDXoX4yJtYszmUhNP87WIISu28oLq94sdhrQc1HBjouaG2DBZRjpFmA7erE2E2mE3gvsd9JGFntBJAtOzIKNt4hkrvRejbZ9fl57OvQpxqZgq5ETLGZB2P+U+q3IaF+yuIRB50ntnyIdq69oraq3Vol+6V+vrttxxVOcYEHE3fm0K7UTR4ZiZ1iHiw889o= x-forefront-antispam-report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:CO1PR11MB4930.namprd11.prod.outlook.com;PTR:;CAT:NONE;SFS:(4636009)(346002)(39860400002)(376002)(396003)(136003)(366004)(66476007)(66446008)(9686003)(8936002)(64756008)(19627235002)(66946007)(5660300002)(66556008)(478600001)(7696005)(186003)(30864003)(33656002)(76116006)(52536014)(26005)(86362001)(83380400001)(8676002)(2906002)(71200400001)(4326008)(107886003)(110136005)(54906003)(55016002)(316002)(53546011)(6506007)(966005)(559001)(579004);DIR:OUT;SFP:1102; x-ms-exchange-antispam-messagedata: =?us-ascii?Q?H9T8outmMAxTYOA5FX6LOr1ZpsQjkNDtO0w1I1ngMorqKf9Ha8/YY2Z/idKK?= =?us-ascii?Q?k0Yqf6PrqJ57zG5COX4WP4ClVJDBevdVs8ProVkWfWPm/ynZ38cHXab+75BX?= =?us-ascii?Q?ornlQ/tRvhLBNNXvqp+SNNGjkmxSY1fBMnXqaGnQRhy+66rTkSGsoBHyhuiW?= =?us-ascii?Q?v0MrjZghB38Z7aNlK1lAJzKy5hr1fm3bNi6eNVpzh6R7LJZebCB1qYaM8JTh?= =?us-ascii?Q?6PSndHA7jc9ioZIq+Hwk/fusf253GE0mGWC/MW3MMyC4XUNzE1NPymu5ALUO?= =?us-ascii?Q?haBG7GXnhBFG/5BvUcWSD0+7WXUOp+Xg+mUTjmB5fBcXfimNuTnoXtaMutuf?= =?us-ascii?Q?tFqd8+FokXuAfv7XilQNn+KQkSYHlKAQY+lEOmgDpqqmTlo3shpCgeuElTco?= =?us-ascii?Q?EYc9T8b56xdUXlfgJdGtb7qThKfjcSxVJpzZrkkvvhFPO8gqvgSAJm1KIEsH?= =?us-ascii?Q?NK7szJhh7n6uf82SHiZCzNx/mNQF6G0n63Yd9OYwbsXiKsmVMquVj0tzAIiS?= =?us-ascii?Q?nJCJG335fbkKZDXxV055+apOCbnF++JRbcuw0JMsQ3LCe3duExyrWZgNiacT?= =?us-ascii?Q?C7zlLXETefOlMmNtvqLb0XclKW0rf7Widwz9m0luCEUKeI4PthiKDr5LF8TC?= =?us-ascii?Q?7CyDhH4ZBu9BzIM4GYLWG8hwQq22Fk+Wo5jkeaYlZwOYhGsDUM4DC3Kqa/Vp?= =?us-ascii?Q?QzUolFSx1aPqMXcJBQ0zCFb1Tdt42Woha7PeQSV1ToS77qSLocHoBM6zuMK6?= =?us-ascii?Q?AcHJ6JEiQm5KCZBkLPQ4pyvuBwTDTRHDz+gIKTQlK9EFwTCub+YPjCByHij7?= =?us-ascii?Q?fWR9XfO3vGFV8HHlMQO2s0IcQQ7E0d6P7vj7ef9H+LPDowNG2YVMC4/a/2S9?= =?us-ascii?Q?7yimEUJYjU689Hup4QxONyJ9l9Bgfndpurozp1e1ycxdhCF09cIPQGQAvt+F?= =?us-ascii?Q?sGinvh5lCf15tOryLoJnGLzfnATSSEvGZgs8kAFvXg8=3D?= MIME-Version: 1.0 X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-AuthSource: CO1PR11MB4930.namprd11.prod.outlook.com X-MS-Exchange-CrossTenant-Network-Message-Id: 784ec857-eebc-4d90-c75b-08d8bc72929f X-MS-Exchange-CrossTenant-originalarrivaltime: 19 Jan 2021 12:05:54.3690 (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: v1WI+7qJzYAC7fnnazzflROLXaE5o76QcLTbQiE1MjFrsTqQqqYKDhW7pc61re65A4ZJQDoJxxQftkVzl5luVQ== X-MS-Exchange-Transport-CrossTenantHeadersStamped: CO1PR11MB5010 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 If this patch is not updated, please carry the original Reviewed-by tag. Reviewed-by: Ray Ni > -----Original Message----- > From: Lou, Yun > Sent: Sunday, January 17, 2021 10:16 PM > To: devel@edk2.groups.io > Cc: Lou, Yun ; Ni, Ray ; Dong, Eric = ; Laszlo Ersek > ; Kumar, Rahul1 > Subject: [PATCH v7 2/2] UefiCpuPkg/CpuCacheInfoLib: Add new CpuCacheInfoL= ib. >=20 > REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3D3105 >=20 > This new library uses a platform agnostic algorithm to get CPU > cache information. It provides user with an API(GetCpuCacheInfo) > to get detailed CPU cache information by each package, each core > type included in this package, and each cache level & type. > This library can be used by code that produces SMBIOS_TABLE_TYPE7 > SMBIOS table. >=20 > Signed-off-by: Jason Lou > Cc: Ray Ni > Cc: Eric Dong > Cc: Laszlo Ersek > Cc: Rahul Kumar > --- > UefiCpuPkg/Library/CpuCacheInfoLib/CpuCacheInfoLib.c | 441 +++++= +++++++++++++++ > UefiCpuPkg/Library/CpuCacheInfoLib/DxeCpuCacheInfoLib.c | 120 +++++= + > UefiCpuPkg/Library/CpuCacheInfoLib/PeiCpuCacheInfoLib.c | 119 +++++= + > UefiCpuPkg/Include/Library/CpuCacheInfoLib.h | 76 ++++ > UefiCpuPkg/Library/CpuCacheInfoLib/CpuCacheInfoLib.uni | 15 + > UefiCpuPkg/Library/CpuCacheInfoLib/DxeCpuCacheInfoLib.inf | 43 ++ > UefiCpuPkg/Library/CpuCacheInfoLib/InternalCpuCacheInfoLib.h | 159 +++++= ++ > UefiCpuPkg/Library/CpuCacheInfoLib/PeiCpuCacheInfoLib.inf | 43 ++ > UefiCpuPkg/UefiCpuPkg.dec | 3 + > UefiCpuPkg/UefiCpuPkg.dsc | 4 + > 10 files changed, 1023 insertions(+) >=20 > diff --git a/UefiCpuPkg/Library/CpuCacheInfoLib/CpuCacheInfoLib.c > b/UefiCpuPkg/Library/CpuCacheInfoLib/CpuCacheInfoLib.c > new file mode 100644 > index 000000000000..6b87be261acf > --- /dev/null > +++ b/UefiCpuPkg/Library/CpuCacheInfoLib/CpuCacheInfoLib.c > @@ -0,0 +1,441 @@ > +/** @file >=20 > + Provides cache info for each package, core type, cache level and cache= type. >=20 > + >=20 > + Copyright (c) 2020 Intel Corporation. All rights reserved.
>=20 > + SPDX-License-Identifier: BSD-2-Clause-Patent >=20 > + >=20 > +**/ >=20 > + >=20 > +#include "InternalCpuCacheInfoLib.h" >=20 > + >=20 > +/** >=20 > + Print CpuCacheInfo array. >=20 > + >=20 > + @param[in] CpuCacheInfo Pointer to the CpuCacheInfo array. >=20 > + @param[in] CpuCacheInfoCount The length of CpuCacheInfo array. >=20 > + >=20 > +**/ >=20 > +VOID >=20 > +CpuCacheInfoPrintCpuCacheInfoTable ( >=20 > + IN CPU_CACHE_INFO *CpuCacheInfo, >=20 > + IN UINTN CpuCacheInfoCount >=20 > + ) >=20 > +{ >=20 > + UINTN Index; >=20 > + >=20 > + DEBUG ((DEBUG_INFO, "+-------+----------------------------------------= ---------------------------------------+\n")); >=20 > + DEBUG ((DEBUG_INFO, "| Index | Packge CoreType CacheLevel CacheType= CacheWays CacheSizeinKB CacheCount > |\n")); >=20 > + DEBUG ((DEBUG_INFO, "+-------+----------------------------------------= ---------------------------------------+\n")); >=20 > + >=20 > + for (Index =3D 0; Index < CpuCacheInfoCount; Index++) { >=20 > + DEBUG ((DEBUG_INFO, "| %4x | %4x %2x %2x %2x = %4x %8x %4x |\n", Index, >=20 > + CpuCacheInfo[Index].Package, CpuCacheInfo[Index].CoreType, CpuCa= cheInfo[Index].CacheLevel, >=20 > + CpuCacheInfo[Index].CacheType, CpuCacheInfo[Index].CacheWays, Cp= uCacheInfo[Index].CacheSizeinKB, >=20 > + CpuCacheInfo[Index].CacheCount)); >=20 > + } >=20 > + >=20 > + DEBUG ((DEBUG_INFO, "+-------+----------------------------------------= ---------------------------------------+\n")); >=20 > +} >=20 > + >=20 > +/** >=20 > + Get the total number of package and package ID in the platform. >=20 > + >=20 > + @param[in] ProcessorInfo Pointer to the ProcessorInfo array= . >=20 > + @param[in] NumberOfProcessors Total number of logical processors= in the platform. >=20 > + @param[in, out] Package Pointer to the Package array. >=20 > + >=20 > + @retval Return the total number of package and package ID in the plat= form. >=20 > +**/ >=20 > +UINT32 >=20 > +CpuCacheInfoGetNumberOfPackages ( >=20 > + IN CPUID_PROCESSOR_INFO *ProcessorInfo, >=20 > + IN UINTN NumberOfProcessors, >=20 > + IN OUT UINT32 *Package >=20 > + ) >=20 > +{ >=20 > + UINTN ProcessorIndex; >=20 > + UINT32 PackageIndex; >=20 > + UINT32 PackageCount; >=20 > + UINT32 CurrentPackage; >=20 > + >=20 > + PackageCount =3D 0; >=20 > + >=20 > + for (ProcessorIndex =3D 0; ProcessorIndex < NumberOfProcessors; Proces= sorIndex++) { >=20 > + CurrentPackage =3D ProcessorInfo[ProcessorIndex].Package; >=20 > + >=20 > + // >=20 > + // For the package that already exists in Package array, break out t= he loop. >=20 > + // >=20 > + for (PackageIndex =3D 0; PackageIndex < PackageCount; PackageIndex++= ) { >=20 > + if (CurrentPackage =3D=3D Package[PackageIndex]) { >=20 > + break; >=20 > + } >=20 > + } >=20 > + >=20 > + // >=20 > + // For the new package, save it in Package array. >=20 > + // >=20 > + if (PackageIndex =3D=3D PackageCount) { >=20 > + ASSERT (PackageCount < MAX_NUM_OF_PACKAGE); >=20 > + Package[PackageCount++] =3D CurrentPackage; >=20 > + } >=20 > + } >=20 > + >=20 > + return PackageCount; >=20 > +} >=20 > + >=20 > +/** >=20 > + Get the number of CoreType of requested package. >=20 > + >=20 > + @param[in] ProcessorInfo Pointer to the ProcessorInfo array. >=20 > + @param[in] NumberOfProcessors Total number of logical processors in = the platform. >=20 > + @param[in] Package The requested package number. >=20 > + >=20 > + @retval Return the number of CoreType of requested package. >=20 > +**/ >=20 > +UINTN >=20 > +CpuCacheInfoGetNumberOfCoreTypePerPackage( >=20 > + IN CPUID_PROCESSOR_INFO *ProcessorInfo, >=20 > + IN UINTN NumberOfProcessors, >=20 > + IN UINTN Package >=20 > + ) >=20 > +{ >=20 > + UINTN ProcessorIndex; >=20 > + // >=20 > + // Core Type value comes from CPUID.1Ah.EAX[31:24]. >=20 > + // So max number of core types should be MAX_UINT8. >=20 > + // >=20 > + UINT8 CoreType[MAX_UINT8]; >=20 > + UINTN CoreTypeIndex; >=20 > + UINTN CoreTypeCount; >=20 > + UINT8 CurrentCoreType; >=20 > + >=20 > + // >=20 > + // CoreType array is empty. >=20 > + // >=20 > + CoreTypeCount =3D 0; >=20 > + >=20 > + for (ProcessorIndex =3D 0; ProcessorIndex < NumberOfProcessors; Proces= sorIndex++) { >=20 > + CurrentCoreType =3D ProcessorInfo[ProcessorIndex].CoreType; >=20 > + >=20 > + if (ProcessorInfo[ProcessorIndex].Package !=3D Package) { >=20 > + continue; >=20 > + } >=20 > + >=20 > + // >=20 > + // For the type that already exists in CoreType array, break out the= loop. >=20 > + // >=20 > + for (CoreTypeIndex =3D 0; CoreTypeIndex < CoreTypeCount; CoreTypeInd= ex++) { >=20 > + if (CurrentCoreType =3D=3D CoreType[CoreTypeIndex]) { >=20 > + break; >=20 > + } >=20 > + } >=20 > + >=20 > + // >=20 > + // For the new type, save it in CoreType array. >=20 > + // >=20 > + if (CoreTypeIndex =3D=3D CoreTypeCount) { >=20 > + ASSERT (CoreTypeCount < MAX_UINT8); >=20 > + CoreType[CoreTypeCount++] =3D CurrentCoreType; >=20 > + } >=20 > + } >=20 > + >=20 > + return CoreTypeCount; >=20 > +} >=20 > + >=20 > +/** >=20 > + Collect core and cache information of calling processor via CPUID inst= ructions. >=20 > + >=20 > + @param[in, out] Buffer The pointer to private data buffer= . >=20 > +**/ >=20 > +VOID >=20 > +EFIAPI >=20 > +CpuCacheInfoCollectCoreAndCacheData ( >=20 > + IN OUT VOID *Buffer >=20 > + ) >=20 > +{ >=20 > + UINTN ProcessorIndex; >=20 > + UINT32 CpuidMaxInput; >=20 > + UINT8 CacheParamLeafIndex; >=20 > + CPUID_CACHE_PARAMS_EAX CacheParamEax; >=20 > + CPUID_CACHE_PARAMS_EBX CacheParamEbx; >=20 > + UINT32 CacheParamEcx; >=20 > + CPUID_NATIVE_MODEL_ID_AND_CORE_TYPE_EAX NativeModelIdAndCoreTypeEax; >=20 > + COLLECT_CPUID_CACHE_DATA_CONTEXT *Context; >=20 > + CPUID_CACHE_DATA *CacheData; >=20 > + >=20 > + Context =3D (COLLECT_CPUID_CACHE_DATA_CONTEXT *)Buffer; >=20 > + ProcessorIndex =3D CpuCacheInfoWhoAmI (Context->MpServices); >=20 > + CacheData =3D &Context->CacheData[MAX_NUM_OF_CACHE_PARAMS_LEAF * Proce= ssorIndex]; >=20 > + >=20 > + AsmCpuid (CPUID_SIGNATURE, &CpuidMaxInput, NULL, NULL, NULL); >=20 > + >=20 > + // >=20 > + // get CoreType if CPUID_HYBRID_INFORMATION leaf is supported. >=20 > + // >=20 > + Context->ProcessorInfo[ProcessorIndex].CoreType =3D 0; >=20 > + if (CpuidMaxInput >=3D CPUID_HYBRID_INFORMATION) { >=20 > + AsmCpuidEx (CPUID_HYBRID_INFORMATION, CPUID_HYBRID_INFORMATION_SUB_L= EAF, > &NativeModelIdAndCoreTypeEax.Uint32, NULL, NULL, NULL); >=20 > + Context->ProcessorInfo[ProcessorIndex].CoreType =3D (UINT8) NativeMo= delIdAndCoreTypeEax.Bits.CoreType; >=20 > + } >=20 > + >=20 > + // >=20 > + // cache hierarchy starts with an index value of 0. >=20 > + // >=20 > + CacheParamLeafIndex =3D 0; >=20 > + >=20 > + while (CacheParamLeafIndex < MAX_NUM_OF_CACHE_PARAMS_LEAF) { >=20 > + AsmCpuidEx (CPUID_CACHE_PARAMS, CacheParamLeafIndex, &CacheParamEax.= Uint32, &CacheParamEbx.Uint32, > &CacheParamEcx, NULL); >=20 > + >=20 > + if (CacheParamEax.Bits.CacheType =3D=3D 0) { >=20 > + break; >=20 > + } >=20 > + >=20 > + CacheData[CacheParamLeafIndex].CacheLevel =3D (UINT8)CacheParamE= ax.Bits.CacheLevel; >=20 > + CacheData[CacheParamLeafIndex].CacheType =3D (UINT8)CacheParamE= ax.Bits.CacheType; >=20 > + CacheData[CacheParamLeafIndex].CacheWays =3D (UINT16)CacheParam= Ebx.Bits.Ways; >=20 > + CacheData[CacheParamLeafIndex].CacheShareBits =3D > (UINT16)CacheParamEax.Bits.MaximumAddressableIdsForLogicalProcessors; >=20 > + CacheData[CacheParamLeafIndex].CacheSizeinKB =3D (CacheParamEbx.Bit= s.Ways + 1) * >=20 > + (CacheParamEbx.Bits.LinePartitions + 1) * (CacheParamEbx.Bits.Li= neSize + 1) * (CacheParamEcx + 1) / SIZE_1KB; >=20 > + >=20 > + CacheParamLeafIndex++; >=20 > + } >=20 > +} >=20 > + >=20 > +/** >=20 > + Collect CacheInfo data from the CacheData. >=20 > + >=20 > + @param[in] CacheData Pointer to the CacheData array. >=20 > + @param[in] ProcessorInfo Pointer to the ProcessorInfo array= . >=20 > + @param[in] NumberOfProcessors Total number of logical processors= in the platform. >=20 > + @param[in, out] CacheInfo Pointer to the CacheInfo array. >=20 > + @param[in, out] CacheInfoCount As input, point to the length of r= esponse CacheInfo array. >=20 > + As output, point to the actual len= gth of response CacheInfo array. >=20 > + >=20 > + @retval EFI_SUCCESS Function completed successfull= y. >=20 > + @retval EFI_OUT_OF_RESOURCES Required resources could not b= e allocated. >=20 > + @retval EFI_BUFFER_TOO_SMALL CacheInfoCount is too small to= hold the response CacheInfo >=20 > + array. CacheInfoCount has been= updated with the length needed >=20 > + to complete the request. >=20 > +**/ >=20 > +EFI_STATUS >=20 > +CpuCacheInfoCollectCpuCacheInfoData ( >=20 > + IN CPUID_CACHE_DATA *CacheData, >=20 > + IN CPUID_PROCESSOR_INFO *ProcessorInfo, >=20 > + IN UINTN NumberOfProcessors, >=20 > + IN OUT CPU_CACHE_INFO *CacheInfo, >=20 > + IN OUT UINTN *CacheInfoCount >=20 > + ) >=20 > +{ >=20 > + EFI_STATUS Status; >=20 > + UINT32 NumberOfPackage; >=20 > + UINT32 Package[MAX_NUM_OF_PACKAGE]; >=20 > + UINTN PackageIndex; >=20 > + UINTN TotalNumberOfCoreType; >=20 > + UINTN MaxCacheInfoCount; >=20 > + CPU_CACHE_INFO *LocalCacheInfo; >=20 > + UINTN CacheInfoIndex; >=20 > + UINTN LocalCacheInfoCount; >=20 > + UINTN Index; >=20 > + UINTN NextIndex; >=20 > + >=20 > + // >=20 > + // Get number of Packages and Package ID. >=20 > + // >=20 > + NumberOfPackage =3D CpuCacheInfoGetNumberOfPackages (ProcessorInfo, Nu= mberOfProcessors, Package); >=20 > + >=20 > + // >=20 > + // Get number of core types for each package and count the total numbe= r. >=20 > + // E.g. If Package1 and Package2 both have 2 core types, the total num= ber is 4. >=20 > + // >=20 > + TotalNumberOfCoreType =3D 0; >=20 > + for (PackageIndex =3D 0; PackageIndex < NumberOfPackage; PackageIndex+= +) { >=20 > + TotalNumberOfCoreType +=3D CpuCacheInfoGetNumberOfCoreTypePerPackage= (ProcessorInfo, NumberOfProcessors, > Package[PackageIndex]); >=20 > + } >=20 > + >=20 > + MaxCacheInfoCount =3D TotalNumberOfCoreType * MAX_NUM_OF_CACHE_PARAMS_= LEAF; >=20 > + LocalCacheInfo =3D AllocatePages (EFI_SIZE_TO_PAGES (MaxCacheInfoCount= * sizeof (*LocalCacheInfo))); >=20 > + ASSERT (LocalCacheInfo !=3D NULL); >=20 > + if (LocalCacheInfo =3D=3D NULL) { >=20 > + return EFI_OUT_OF_RESOURCES; >=20 > + } >=20 > + >=20 > + LocalCacheInfoCount =3D 0; >=20 > + >=20 > + for (Index =3D 0; Index < NumberOfProcessors * MAX_NUM_OF_CACHE_PARAMS= _LEAF; Index++) { >=20 > + if (CacheData[Index].CacheSizeinKB =3D=3D 0) { >=20 > + continue; >=20 > + } >=20 > + >=20 > + // >=20 > + // For the sharing caches, clear their CacheSize. >=20 > + // >=20 > + for (NextIndex =3D Index + 1; NextIndex < NumberOfProcessors * MAX_N= UM_OF_CACHE_PARAMS_LEAF; NextIndex++) { >=20 > + if (CacheData[NextIndex].CacheSizeinKB =3D=3D 0) { >=20 > + continue; >=20 > + } >=20 > + >=20 > + if (CacheData[Index].CacheLevel =3D=3D CacheData[NextIndex].CacheL= evel && >=20 > + CacheData[Index].CacheType =3D=3D CacheData[NextIndex].CacheTy= pe && >=20 > + ProcessorInfo[Index / MAX_NUM_OF_CACHE_PARAMS_LEAF].Package = =3D=3D ProcessorInfo[NextIndex / > MAX_NUM_OF_CACHE_PARAMS_LEAF].Package && >=20 > + ProcessorInfo[Index / MAX_NUM_OF_CACHE_PARAMS_LEAF].CoreType = =3D=3D ProcessorInfo[NextIndex / > MAX_NUM_OF_CACHE_PARAMS_LEAF].CoreType && >=20 > + (ProcessorInfo[Index / MAX_NUM_OF_CACHE_PARAMS_LEAF].ApicId & = ~CacheData[Index].CacheShareBits) =3D=3D >=20 > + (ProcessorInfo[NextIndex / MAX_NUM_OF_CACHE_PARAMS_LEAF].ApicI= d & ~CacheData[NextIndex].CacheShareBits)) > { >=20 > + CacheData[NextIndex].CacheSizeinKB =3D 0; // uses the sharing ca= che >=20 > + } >=20 > + } >=20 > + >=20 > + // >=20 > + // For the cache that already exists in LocalCacheInfo, increase its= CacheCount. >=20 > + // >=20 > + for (CacheInfoIndex =3D 0; CacheInfoIndex < LocalCacheInfoCount; Cac= heInfoIndex++) { >=20 > + if (LocalCacheInfo[CacheInfoIndex].Package =3D=3D ProcessorInfo= [Index / MAX_NUM_OF_CACHE_PARAMS_LEAF].Package > && >=20 > + LocalCacheInfo[CacheInfoIndex].CoreType =3D=3D ProcessorInfo= [Index / > MAX_NUM_OF_CACHE_PARAMS_LEAF].CoreType && >=20 > + LocalCacheInfo[CacheInfoIndex].CacheLevel =3D=3D CacheData[Ind= ex].CacheLevel && >=20 > + LocalCacheInfo[CacheInfoIndex].CacheType =3D=3D CacheData[Ind= ex].CacheType) { >=20 > + LocalCacheInfo[CacheInfoIndex].CacheCount++; >=20 > + break; >=20 > + } >=20 > + } >=20 > + >=20 > + // >=20 > + // For the new cache with different Package, CoreType, CacheLevel or= CacheType, copy its >=20 > + // data into LocalCacheInfo buffer. >=20 > + // >=20 > + if (CacheInfoIndex =3D=3D LocalCacheInfoCount) { >=20 > + ASSERT (LocalCacheInfoCount < MaxCacheInfoCount); >=20 > + >=20 > + LocalCacheInfo[LocalCacheInfoCount].Package =3D ProcessorInf= o[Index / > MAX_NUM_OF_CACHE_PARAMS_LEAF].Package; >=20 > + LocalCacheInfo[LocalCacheInfoCount].CoreType =3D ProcessorInf= o[Index / > MAX_NUM_OF_CACHE_PARAMS_LEAF].CoreType; >=20 > + LocalCacheInfo[LocalCacheInfoCount].CacheLevel =3D CacheData[In= dex].CacheLevel; >=20 > + LocalCacheInfo[LocalCacheInfoCount].CacheType =3D CacheData[In= dex].CacheType; >=20 > + LocalCacheInfo[LocalCacheInfoCount].CacheWays =3D CacheData[In= dex].CacheWays; >=20 > + LocalCacheInfo[LocalCacheInfoCount].CacheSizeinKB =3D CacheData[In= dex].CacheSizeinKB; >=20 > + LocalCacheInfo[LocalCacheInfoCount].CacheCount =3D 1; >=20 > + >=20 > + LocalCacheInfoCount++; >=20 > + } >=20 > + } >=20 > + >=20 > + if (*CacheInfoCount < LocalCacheInfoCount) { >=20 > + Status =3D EFI_BUFFER_TOO_SMALL; >=20 > + } else { >=20 > + CopyMem (CacheInfo, LocalCacheInfo, sizeof (*CacheInfo) * LocalCache= InfoCount); >=20 > + DEBUG_CODE ( >=20 > + CpuCacheInfoPrintCpuCacheInfoTable (CacheInfo, LocalCacheInfoCount= ); >=20 > + ); >=20 > + Status =3D EFI_SUCCESS; >=20 > + } >=20 > + >=20 > + *CacheInfoCount =3D LocalCacheInfoCount; >=20 > + >=20 > + FreePages (LocalCacheInfo, EFI_SIZE_TO_PAGES (MaxCacheInfoCount * size= of (*LocalCacheInfo))); >=20 > + >=20 > + return Status; >=20 > +} >=20 > + >=20 > +/** >=20 > + Get CpuCacheInfo data array. >=20 > + >=20 > + @param[in, out] CpuCacheInfo Pointer to the CpuCacheInfo array. >=20 > + @param[in, out] CpuCacheInfoCount As input, point to the length of r= esponse CpuCacheInfo array. >=20 > + As output, point to the actual len= gth of response CpuCacheInfo array. >=20 > + >=20 > + @retval EFI_SUCCESS Function completed successfull= y. >=20 > + @retval EFI_INVALID_PARAMETER CpuCacheInfoCount is NULL. >=20 > + @retval EFI_INVALID_PARAMETER CpuCacheInfo is NULL while Cpu= CacheInfoCount contains the value >=20 > + greater than zero. >=20 > + @retval EFI_UNSUPPORTED Processor does not support CPU= ID_CACHE_PARAMS Leaf. >=20 > + @retval EFI_NOT_FOUND EDKII_PEI_MP_SERVICES2_PPI or = EFI_MP_SERVICES_PROTOCOL interface >=20 > + is not found. >=20 > + @retval EFI_OUT_OF_RESOURCES Required resources could not b= e allocated. >=20 > + @retval EFI_BUFFER_TOO_SMALL CpuCacheInfoCount is too small= to hold the response CpuCacheInfo >=20 > + array. CpuCacheInfoCount has b= een updated with the length needed >=20 > + to complete the request. >=20 > +**/ >=20 > +EFI_STATUS >=20 > +EFIAPI >=20 > +GetCpuCacheInfo ( >=20 > + IN OUT CPU_CACHE_INFO *CpuCacheInfo, >=20 > + IN OUT UINTN *CpuCacheInfoCount >=20 > + ) >=20 > +{ >=20 > + EFI_STATUS Status; >=20 > + UINT32 CpuidMaxInput; >=20 > + UINT32 NumberOfProcessors; >=20 > + UINTN CacheDataCount; >=20 > + UINTN ProcessorIndex; >=20 > + EFI_PROCESSOR_INFORMATION ProcessorInfo; >=20 > + COLLECT_CPUID_CACHE_DATA_CONTEXT Context; >=20 > + >=20 > + if (CpuCacheInfoCount =3D=3D NULL) { >=20 > + return EFI_INVALID_PARAMETER; >=20 > + } >=20 > + >=20 > + if (*CpuCacheInfoCount !=3D 0 && CpuCacheInfo =3D=3D NULL) { >=20 > + return EFI_INVALID_PARAMETER; >=20 > + } >=20 > + >=20 > + AsmCpuid (CPUID_SIGNATURE, &CpuidMaxInput, NULL, NULL, NULL); >=20 > + if (CpuidMaxInput < CPUID_CACHE_PARAMS) { >=20 > + return EFI_UNSUPPORTED; >=20 > + } >=20 > + >=20 > + // >=20 > + // Initialize COLLECT_CPUID_CACHE_DATA_CONTEXT.MpServices. >=20 > + // >=20 > + Status =3D CpuCacheInfoGetMpServices (&Context.MpServices); >=20 > + if (EFI_ERROR(Status)) { >=20 > + return Status; >=20 > + } >=20 > + >=20 > + NumberOfProcessors =3D CpuCacheInfoGetNumberOfProcessors (Context.MpSe= rvices); >=20 > + >=20 > + // >=20 > + // Initialize COLLECT_CPUID_CACHE_DATA_CONTEXT.ProcessorInfo. >=20 > + // >=20 > + Context.ProcessorInfo =3D AllocatePages (EFI_SIZE_TO_PAGES (NumberOfPr= ocessors * sizeof (*Context.ProcessorInfo))); >=20 > + ASSERT (Context.ProcessorInfo !=3D NULL); >=20 > + if (Context.ProcessorInfo =3D=3D NULL) { >=20 > + return EFI_OUT_OF_RESOURCES; >=20 > + } >=20 > + // >=20 > + // Initialize COLLECT_CPUID_CACHE_DATA_CONTEXT.CacheData. >=20 > + // CacheData array consists of CPUID_CACHE_DATA data structure for eac= h Cpuid Cache Parameter Leaf >=20 > + // per logical processor. The array begin with data of each Cache Para= meter Leaf of processor 0, followed >=20 > + // by data of each Cache Parameter Leaf of processor 1 ... >=20 > + // >=20 > + CacheDataCount =3D NumberOfProcessors * MAX_NUM_OF_CACHE_PARAMS_LEAF; >=20 > + Context.CacheData =3D AllocatePages (EFI_SIZE_TO_PAGES (CacheDataCount= * sizeof (*Context.CacheData))); >=20 > + ASSERT (Context.CacheData !=3D NULL); >=20 > + if (Context.CacheData =3D=3D NULL) { >=20 > + FreePages (Context.ProcessorInfo, EFI_SIZE_TO_PAGES (NumberOfProcess= ors * sizeof (*Context.ProcessorInfo))); >=20 > + return EFI_OUT_OF_RESOURCES; >=20 > + } >=20 > + >=20 > + ZeroMem (Context.CacheData, CacheDataCount * sizeof (*Context.CacheDat= a)); >=20 > + >=20 > + // >=20 > + // Collect Package ID and APIC ID of all processors. >=20 > + // >=20 > + for (ProcessorIndex =3D 0; ProcessorIndex < NumberOfProcessors; Proces= sorIndex++) { >=20 > + CpuCacheInfoGetProcessorInfo (Context.MpServices, ProcessorIndex, &P= rocessorInfo); >=20 > + Context.ProcessorInfo[ProcessorIndex].Package =3D ProcessorInfo.Loca= tion.Package; >=20 > + Context.ProcessorInfo[ProcessorIndex].ApicId =3D (UINT32) Processor= Info.ProcessorId; >=20 > + } >=20 > + >=20 > + // >=20 > + // Wakeup all processors for CacheData(core type and cache data) colle= ction. >=20 > + // >=20 > + CpuCacheInfoStartupAllCPUs (Context.MpServices, CpuCacheInfoCollectCor= eAndCacheData, &Context); >=20 > + >=20 > + // >=20 > + // Collect CpuCacheInfo data from CacheData. >=20 > + // >=20 > + Status =3D CpuCacheInfoCollectCpuCacheInfoData (Context.CacheData, Con= text.ProcessorInfo, NumberOfProcessors, > CpuCacheInfo, CpuCacheInfoCount); >=20 > + >=20 > + FreePages (Context.CacheData, EFI_SIZE_TO_PAGES (CacheDataCount * size= of (*Context.CacheData))); >=20 > + FreePages (Context.ProcessorInfo, EFI_SIZE_TO_PAGES (NumberOfProcessor= s * sizeof (*Context.ProcessorInfo))); >=20 > + >=20 > + return Status; >=20 > +} >=20 > diff --git a/UefiCpuPkg/Library/CpuCacheInfoLib/DxeCpuCacheInfoLib.c > b/UefiCpuPkg/Library/CpuCacheInfoLib/DxeCpuCacheInfoLib.c > new file mode 100644 > index 000000000000..bb788e36146b > --- /dev/null > +++ b/UefiCpuPkg/Library/CpuCacheInfoLib/DxeCpuCacheInfoLib.c > @@ -0,0 +1,120 @@ > +/** @file >=20 > + Provides cache info for each package, core type, cache level and cache= type. >=20 > + >=20 > + Copyright (c) 2020 Intel Corporation. All rights reserved.
>=20 > + SPDX-License-Identifier: BSD-2-Clause-Patent >=20 > + >=20 > +**/ >=20 > + >=20 > +#include >=20 > +#include >=20 > +#include >=20 > +#include >=20 > +#include >=20 > +#include >=20 > + >=20 > +/** >=20 > + Get EFI_MP_SERVICES_PROTOCOL pointer. >=20 > + >=20 > + @param[out] MpServices A pointer to the buffer where EFI_MP_SERVICE= S_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 > +CpuCacheInfoGetMpServices ( >=20 > + OUT MP_SERVICES *MpServices >=20 > + ) >=20 > +{ >=20 > + EFI_STATUS Status; >=20 > + >=20 > + Status =3D gBS->LocateProtocol (&gEfiMpServiceProtocolGuid, NULL, (VOI= D **)&MpServices->Protocol); >=20 > + ASSERT_EFI_ERROR (Status); >=20 > + >=20 > + return Status; >=20 > +} >=20 > + >=20 > +/** >=20 > + Activate all of the logical processors. >=20 > + >=20 > + @param[in] MpServices MP_SERVICES structure. >=20 > + @param[in] Procedure A pointer to the function to be run on= enabled logical processors. >=20 > + @param[in] ProcedureArgument The parameter passed into Procedure fo= r all enabled logical processors. >=20 > +**/ >=20 > +VOID >=20 > +CpuCacheInfoStartupAllCPUs ( >=20 > + IN MP_SERVICES MpServices, >=20 > + IN EFI_AP_PROCEDURE Procedure, >=20 > + IN VOID *ProcedureArgument >=20 > + ) >=20 > +{ >=20 > + EFI_STATUS Status; >=20 > + >=20 > + Status =3D MpServices.Protocol->StartupAllAPs (MpServices.Protocol, Pr= ocedure, FALSE, NULL, 0, ProcedureArgument, > NULL); >=20 > + ASSERT_EFI_ERROR (Status); >=20 > + >=20 > + Procedure (ProcedureArgument); >=20 > +} >=20 > + >=20 > +/** >=20 > + Get detailed information of the requested logical processor. >=20 > + >=20 > + @param[in] MpServices MP_SERVICES structure. >=20 > + @param[in] ProcessorNum The requested logical processor number= . >=20 > + @param[out] ProcessorInfo A pointer to the buffer where the proc= essor information is stored >=20 > +**/ >=20 > +VOID >=20 > +CpuCacheInfoGetProcessorInfo ( >=20 > + IN MP_SERVICES MpServices, >=20 > + IN UINTN ProcessorNum, >=20 > + OUT EFI_PROCESSOR_INFORMATION *ProcessorInfo >=20 > + ) >=20 > +{ >=20 > + EFI_STATUS Status; >=20 > + >=20 > + Status =3D MpServices.Protocol->GetProcessorInfo (MpServices.Protocol,= ProcessorNum, ProcessorInfo); >=20 > + ASSERT_EFI_ERROR (Status); >=20 > +} >=20 > + >=20 > +/** >=20 > + Get the logical processor number. >=20 > + >=20 > + @param[in] MpServices MP_SERVICES structure. >=20 > + >=20 > + @retval Return the logical processor number. >=20 > +**/ >=20 > +UINT32 >=20 > +CpuCacheInfoWhoAmI ( >=20 > + IN MP_SERVICES MpServices >=20 > + ) >=20 > +{ >=20 > + EFI_STATUS Status; >=20 > + UINTN ProcessorNum; >=20 > + >=20 > + Status =3D MpServices.Protocol->WhoAmI (MpServices.Protocol, &Processo= rNum); >=20 > + ASSERT_EFI_ERROR (Status); >=20 > + >=20 > + return (UINT32)ProcessorNum; >=20 > +} >=20 > + >=20 > +/** >=20 > + Get the total number of logical processors in the platform. >=20 > + >=20 > + @param[in] MpServices MP_SERVICES structure. >=20 > + >=20 > + @retval Return the total number of logical processors. >=20 > +**/ >=20 > +UINT32 >=20 > +CpuCacheInfoGetNumberOfProcessors ( >=20 > + IN MP_SERVICES MpServices >=20 > + ) >=20 > +{ >=20 > + EFI_STATUS Status; >=20 > + UINTN NumberOfProcessor; >=20 > + UINTN NumberOfEnabledProcessor; >=20 > + >=20 > + Status =3D MpServices.Protocol->GetNumberOfProcessors (MpServices.Prot= ocol, &NumberOfProcessor, > &NumberOfEnabledProcessor); >=20 > + ASSERT_EFI_ERROR (Status); >=20 > + >=20 > + return (UINT32)NumberOfProcessor; >=20 > +} >=20 > diff --git a/UefiCpuPkg/Library/CpuCacheInfoLib/PeiCpuCacheInfoLib.c > b/UefiCpuPkg/Library/CpuCacheInfoLib/PeiCpuCacheInfoLib.c > new file mode 100644 > index 000000000000..06c160421b00 > --- /dev/null > +++ b/UefiCpuPkg/Library/CpuCacheInfoLib/PeiCpuCacheInfoLib.c > @@ -0,0 +1,119 @@ > +/** @file >=20 > + Provides cache info for each package, core type, cache level and cache= type. >=20 > + >=20 > + Copyright (c) 2020 Intel Corporation. All rights reserved.
>=20 > + SPDX-License-Identifier: BSD-2-Clause-Patent >=20 > + >=20 > +**/ >=20 > + >=20 > +#include >=20 > +#include >=20 > +#include >=20 > +#include >=20 > +#include >=20 > +#include >=20 > +#include >=20 > + >=20 > +/** >=20 > + Get EDKII_PEI_MP_SERVICES2_PPI pointer. >=20 > + >=20 > + @param[out] MpServices A pointer to the buffer where EDKII_PEI_MP_S= ERVICES2_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 > +CpuCacheInfoGetMpServices ( >=20 > + OUT MP_SERVICES *MpServices >=20 > + ) >=20 > +{ >=20 > + EFI_STATUS Status; >=20 > + >=20 > + Status =3D PeiServicesLocatePpi (&gEdkiiPeiMpServices2PpiGuid, 0, NULL= , (VOID **)&MpServices->Ppi); >=20 > + ASSERT_EFI_ERROR (Status); >=20 > + >=20 > + return Status; >=20 > +} >=20 > + >=20 > +/** >=20 > + Activate all of the logical processors. >=20 > + >=20 > + @param[in] MpServices MP_SERVICES structure. >=20 > + @param[in] Procedure A pointer to the function to be run on= enabled logical processors. >=20 > + @param[in] ProcedureArgument The parameter passed into Procedure fo= r all enabled logical processors. >=20 > +**/ >=20 > +VOID >=20 > +CpuCacheInfoStartupAllCPUs ( >=20 > + IN MP_SERVICES MpServices, >=20 > + IN EFI_AP_PROCEDURE Procedure, >=20 > + IN VOID *ProcedureArgument >=20 > + ) >=20 > +{ >=20 > + EFI_STATUS Status; >=20 > + >=20 > + Status =3D MpServices.Ppi->StartupAllCPUs (MpServices.Ppi, Procedure, = 0, ProcedureArgument); >=20 > + ASSERT_EFI_ERROR (Status); >=20 > +} >=20 > + >=20 > +/** >=20 > + Get detailed information of the requested logical processor. >=20 > + >=20 > + @param[in] MpServices MP_SERVICES structure. >=20 > + @param[in] ProcessorNum The requested logical processor number= . >=20 > + @param[out] ProcessorInfo A pointer to the buffer where the proc= essor information is stored >=20 > +**/ >=20 > +VOID >=20 > +CpuCacheInfoGetProcessorInfo ( >=20 > + IN MP_SERVICES MpServices, >=20 > + IN UINTN ProcessorNum, >=20 > + OUT EFI_PROCESSOR_INFORMATION *ProcessorInfo >=20 > + ) >=20 > +{ >=20 > + EFI_STATUS Status; >=20 > + >=20 > + Status =3D MpServices.Ppi->GetProcessorInfo (MpServices.Ppi, Processor= Num, ProcessorInfo); >=20 > + ASSERT_EFI_ERROR (Status); >=20 > +} >=20 > + >=20 > +/** >=20 > + Get the logical processor number. >=20 > + >=20 > + @param[in] MpServices MP_SERVICES structure. >=20 > + >=20 > + @retval Return the logical processor number. >=20 > +**/ >=20 > +UINT32 >=20 > +CpuCacheInfoWhoAmI ( >=20 > + IN MP_SERVICES MpServices >=20 > + ) >=20 > +{ >=20 > + EFI_STATUS Status; >=20 > + UINTN ProcessorNum; >=20 > + >=20 > + Status =3D MpServices.Ppi->WhoAmI (MpServices.Ppi, &ProcessorNum); >=20 > + ASSERT_EFI_ERROR (Status); >=20 > + >=20 > + return (UINT32)ProcessorNum; >=20 > +} >=20 > + >=20 > +/** >=20 > + Get the total number of logical processors in the platform. >=20 > + >=20 > + @param[in] MpServices MP_SERVICES structure. >=20 > + >=20 > + @retval Return the total number of logical processors. >=20 > +**/ >=20 > +UINT32 >=20 > +CpuCacheInfoGetNumberOfProcessors ( >=20 > + IN MP_SERVICES MpServices >=20 > + ) >=20 > +{ >=20 > + EFI_STATUS Status; >=20 > + UINTN NumberOfProcessor; >=20 > + UINTN NumberOfEnabledProcessor; >=20 > + >=20 > + Status =3D MpServices.Ppi->GetNumberOfProcessors (MpServices.Ppi, &Num= berOfProcessor, &NumberOfEnabledProcessor); >=20 > + ASSERT_EFI_ERROR (Status); >=20 > + >=20 > + return (UINT32)NumberOfProcessor; >=20 > +} >=20 > diff --git a/UefiCpuPkg/Include/Library/CpuCacheInfoLib.h b/UefiCpuPkg/In= clude/Library/CpuCacheInfoLib.h > new file mode 100644 > index 000000000000..a23b8b12b5ee > --- /dev/null > +++ b/UefiCpuPkg/Include/Library/CpuCacheInfoLib.h > @@ -0,0 +1,76 @@ > +/** @file >=20 > + Header file for CPU Cache info Library. >=20 > + >=20 > + Copyright (c) 2020, Intel Corporation. All rights reserved.
>=20 > + SPDX-License-Identifier: BSD-2-Clause-Patent >=20 > + >=20 > +**/ >=20 > + >=20 > +#ifndef _CPU_CACHE_INFO_LIB_H_ >=20 > +#define _CPU_CACHE_INFO_LIB_H_ >=20 > + >=20 > +typedef struct { >=20 > + // >=20 > + // Package number. >=20 > + // >=20 > + UINT32 Package; >=20 > + // >=20 > + // Core type of logical processor. >=20 > + // Value =3D CPUID.1Ah:EAX[31:24] >=20 > + // >=20 > + UINT8 CoreType; >=20 > + // >=20 > + // Level of the cache that this package's this type of logical process= or corresponds to. >=20 > + // Value =3D CPUID.04h:EAX[07:05] >=20 > + // >=20 > + UINT8 CacheLevel : 3; >=20 > + // >=20 > + // Type of the cache that this package's this type of logical processo= r corresponds to. >=20 > + // Value =3D CPUID.04h:EAX[04:00] >=20 > + // >=20 > + UINT8 CacheType : 5; >=20 > + // >=20 > + // Ways of associativity. >=20 > + // Value =3D CPUID.04h:EBX[31:22] >=20 > + // >=20 > + UINT16 CacheWays; >=20 > + // >=20 > + // Size of single cache that this package's this type of logical proce= ssor corresponds to. >=20 > + // Value =3D (CPUID.04h:EBX[31:22] + 1) * (CPUID.04h:EBX[21:12] + 1) * >=20 > + // (CPUID.04h:EBX[11:00] + 1) * (CPUID.04h:ECX[31:00] + 1) >=20 > + // >=20 > + UINT32 CacheSizeinKB; >=20 > + // >=20 > + // Number of the cache that this package's this type of logical proces= sor corresponds to. >=20 > + // Have subtracted the number of caches that are shared. >=20 > + // >=20 > + UINT16 CacheCount; >=20 > +} CPU_CACHE_INFO; >=20 > + >=20 > +/** >=20 > + Get CpuCacheInfo data array. >=20 > + >=20 > + @param[in, out] CpuCacheInfo Pointer to the CpuCacheInfo array. >=20 > + @param[in, out] CpuCacheInfoCount As input, point to the length of r= esponse CpuCacheInfo array. >=20 > + As output, point to the actual len= gth of response CpuCacheInfo array. >=20 > + >=20 > + @retval EFI_SUCCESS Function completed successfull= y. >=20 > + @retval EFI_INVALID_PARAMETER CpuCacheInfoCount is NULL. >=20 > + @retval EFI_INVALID_PARAMETER CpuCacheInfo is NULL while Cpu= CacheInfoCount contains the value >=20 > + greater than zero. >=20 > + @retval EFI_UNSUPPORTED Processor does not support CPU= ID_CACHE_PARAMS Leaf. >=20 > + @retval EFI_NOT_FOUND EDKII_PEI_MP_SERVICES2_PPI or = EFI_MP_SERVICES_PROTOCOL interface >=20 > + is not found. >=20 > + @retval EFI_OUT_OF_RESOURCES Required resources could not b= e allocated. >=20 > + @retval EFI_BUFFER_TOO_SMALL CpuCacheInfoCount is too small= to hold the response CpuCacheInfo >=20 > + array. CpuCacheInfoCount has b= een updated with the length needed >=20 > + to complete the request. >=20 > +**/ >=20 > +EFI_STATUS >=20 > +EFIAPI >=20 > +GetCpuCacheInfo ( >=20 > + IN OUT CPU_CACHE_INFO *CpuCacheInfo, >=20 > + IN OUT UINTN *CpuCacheInfoCount >=20 > + ); >=20 > + >=20 > +#endif >=20 > diff --git a/UefiCpuPkg/Library/CpuCacheInfoLib/CpuCacheInfoLib.uni > b/UefiCpuPkg/Library/CpuCacheInfoLib/CpuCacheInfoLib.uni > new file mode 100644 > index 000000000000..1bc801f15f84 > --- /dev/null > +++ b/UefiCpuPkg/Library/CpuCacheInfoLib/CpuCacheInfoLib.uni > @@ -0,0 +1,15 @@ > +// /** @file >=20 > +// CPU Cache Info Library >=20 > +// >=20 > +// Provides cache info for each package, core type, cache level and cach= e type. >=20 > +// >=20 > +// Copyright (c) 2020, Intel Corporation. All rights reserved.
>=20 > +// >=20 > +// SPDX-License-Identifier: BSD-2-Clause-Patent >=20 > +// >=20 > +// **/ >=20 > + >=20 > + >=20 > +#string STR_MODULE_ABSTRACT #language en-US "CPU Cache Info = Library" >=20 > + >=20 > +#string STR_MODULE_DESCRIPTION #language en-US "Provides cache = info for each package, core type, cache level > and cache type." >=20 > diff --git a/UefiCpuPkg/Library/CpuCacheInfoLib/DxeCpuCacheInfoLib.inf > b/UefiCpuPkg/Library/CpuCacheInfoLib/DxeCpuCacheInfoLib.inf > new file mode 100644 > index 000000000000..1fd45380b871 > --- /dev/null > +++ b/UefiCpuPkg/Library/CpuCacheInfoLib/DxeCpuCacheInfoLib.inf > @@ -0,0 +1,43 @@ > +## @file >=20 > +# CPU Cache Info Library instance for DXE driver. >=20 > +# >=20 > +# Provides cache info for each package, core type, cache level and cach= e type. >=20 > +# >=20 > +# Copyright (c) 2020, Intel Corporation. All rights reserved.
>=20 > +# >=20 > +# SPDX-License-Identifier: BSD-2-Clause-Patent >=20 > +# >=20 > +## >=20 > + >=20 > +[Defines] >=20 > + INF_VERSION =3D 0x00010005 >=20 > + BASE_NAME =3D DxeCpuCacheInfoLib >=20 > + FILE_GUID =3D B25C288F-C309-41F1-8325-37E64DC5EA3= D >=20 > + MODULE_TYPE =3D DXE_DRIVER >=20 > + VERSION_STRING =3D 1.0 >=20 > + LIBRARY_CLASS =3D CpuCacheInfoLib|DXE_DRIVER UEFI_APP= LICATION >=20 > + MODULE_UNI_FILE =3D CpuCacheInfoLib.uni >=20 > + >=20 > +[Sources] >=20 > + InternalCpuCacheInfoLib.h >=20 > + CpuCacheInfoLib.c >=20 > + DxeCpuCacheInfoLib.c >=20 > + >=20 > +[Packages] >=20 > + MdePkg/MdePkg.dec >=20 > + UefiCpuPkg/UefiCpuPkg.dec >=20 > + >=20 > +[LibraryClasses] >=20 > + BaseLib >=20 > + DebugLib >=20 > + BaseMemoryLib >=20 > + MemoryAllocationLib >=20 > + UefiBootServicesTableLib >=20 > + >=20 > +[Protocols] >=20 > + gEfiMpServiceProtocolGuid >=20 > + >=20 > +[Pcd] >=20 > + >=20 > +[Depex] >=20 > + TRUE >=20 > diff --git a/UefiCpuPkg/Library/CpuCacheInfoLib/InternalCpuCacheInfoLib.h > b/UefiCpuPkg/Library/CpuCacheInfoLib/InternalCpuCacheInfoLib.h > new file mode 100644 > index 000000000000..de56db9c0cbe > --- /dev/null > +++ b/UefiCpuPkg/Library/CpuCacheInfoLib/InternalCpuCacheInfoLib.h > @@ -0,0 +1,159 @@ > +/** @file >=20 > + Internal header file for CPU Cache info Library. >=20 > + >=20 > + Copyright (c) 2020, Intel Corporation. All rights reserved.
>=20 > + SPDX-License-Identifier: BSD-2-Clause-Patent >=20 > + >=20 > +**/ >=20 > + >=20 > +#ifndef _INTERNAL_CPU_CACHE_INFO_LIB_H_ >=20 > +#define _INTERNAL_CPU_CACHE_INFO_LIB_H_ >=20 > + >=20 > +#include >=20 > +#include >=20 > +#include >=20 > +#include >=20 > +#include >=20 > +#include >=20 > +#include >=20 > +#include >=20 > +#include >=20 > + >=20 > +typedef struct { >=20 > + // >=20 > + // Package ID, the information comes from >=20 > + // EFI_CPU_PHYSICAL_LOCATION.Package >=20 > + // >=20 > + UINT32 Package; >=20 > + // >=20 > + // APIC ID, the information comes from >=20 > + // EFI_PROCESSOR_INFORMATION.ProcessorId >=20 > + // >=20 > + UINT32 ApicId; >=20 > + // >=20 > + // Core type of logical processor. >=20 > + // Value =3D CPUID.1Ah:EAX[31:24] >=20 > + // >=20 > + UINT8 CoreType; >=20 > +} CPUID_PROCESSOR_INFO; >=20 > + >=20 > +typedef struct { >=20 > + // >=20 > + // Level of the cache. >=20 > + // Value =3D CPUID.04h:EAX[07:05] >=20 > + // >=20 > + UINT8 CacheLevel : 3; >=20 > + // >=20 > + // Type of the cache. >=20 > + // Value =3D CPUID.04h:EAX[04:00] >=20 > + // >=20 > + UINT8 CacheType : 5; >=20 > + // >=20 > + // Ways of associativity. >=20 > + // Value =3D CPUID.04h:EBX[31:22] >=20 > + // >=20 > + UINT16 CacheWays; >=20 > + // >=20 > + // Cache share bits. >=20 > + // Value =3D CPUID.04h:EAX[25:14] >=20 > + // >=20 > + UINT16 CacheShareBits; >=20 > + // >=20 > + // Size of single cache. >=20 > + // Value =3D (CPUID.04h:EBX[31:22] + 1) * (CPUID.04h:EBX[21:12] + 1) * >=20 > + // (CPUID.04h:EBX[11:00] + 1) * (CPUID.04h:ECX[31:00] + 1) >=20 > + // >=20 > + UINT32 CacheSizeinKB; >=20 > +} CPUID_CACHE_DATA; >=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 > + CPUID_PROCESSOR_INFO *ProcessorInfo; >=20 > + CPUID_CACHE_DATA *CacheData; >=20 > +} COLLECT_CPUID_CACHE_DATA_CONTEXT; >=20 > + >=20 > + >=20 > +/* >=20 > + Defines the maximum count of Deterministic Cache Parameters Leaf of al= l APs and BSP. >=20 > + To save boot time, skip starting up all APs to calculate each AP's cou= nt of Deterministic >=20 > + Cache Parameters Leaf, so use a definition instead. >=20 > + Anyway, definition value will be checked in CpuCacheInfoCollectCoreAnd= CacheData function. >=20 > +*/ >=20 > +#define MAX_NUM_OF_CACHE_PARAMS_LEAF 6 >=20 > + >=20 > +/* >=20 > + Defines the maximum count of packages. >=20 > +*/ >=20 > +#define MAX_NUM_OF_PACKAGE 100 >=20 > + >=20 > +/** >=20 > + Get EDKII_PEI_MP_SERVICES2_PPI or EFI_MP_SERVICES_PROTOCOL pointer. >=20 > + >=20 > + @param[out] MpServices A pointer to the buffer where EDKII_PEI_MP_S= ERVICES2_PPI or >=20 > + EFI_MP_SERVICES_PROTOCOL is stored >=20 > + >=20 > + @retval EFI_SUCCESS EDKII_PEI_MP_SERVICES2_PPI or EFI_MP_SERVICE= S_PROTOCOL interface is returned >=20 > + @retval EFI_NOT_FOUND EDKII_PEI_MP_SERVICES2_PPI or EFI_MP_SERVICE= S_PROTOCOL interface is not found >=20 > +**/ >=20 > +EFI_STATUS >=20 > +CpuCacheInfoGetMpServices ( >=20 > + OUT MP_SERVICES *MpServices >=20 > + ); >=20 > + >=20 > +/** >=20 > + Activate all of the logical processors. >=20 > + >=20 > + @param[in] MpServices MP_SERVICES structure. >=20 > + @param[in] Procedure A pointer to the function to be run on= enabled logical processors. >=20 > + @param[in] ProcedureArgument The parameter passed into Procedure fo= r all enabled logical processors. >=20 > +**/ >=20 > +VOID >=20 > +CpuCacheInfoStartupAllCPUs ( >=20 > + IN MP_SERVICES MpServices, >=20 > + IN EFI_AP_PROCEDURE Procedure, >=20 > + IN VOID *ProcedureArgument >=20 > + ); >=20 > + >=20 > +/** >=20 > + Get detailed information of the requested logical processor. >=20 > + >=20 > + @param[in] MpServices MP_SERVICES structure. >=20 > + @param[in] ProcessorNum The requested logical processor number= . >=20 > + @param[out] ProcessorInfo A pointer to the buffer where the proc= essor information is stored >=20 > +**/ >=20 > +VOID >=20 > +CpuCacheInfoGetProcessorInfo ( >=20 > + IN MP_SERVICES MpServices, >=20 > + IN UINTN ProcessorNum, >=20 > + OUT EFI_PROCESSOR_INFORMATION *ProcessorInfo >=20 > + ); >=20 > + >=20 > +/** >=20 > + Get the logical processor number. >=20 > + >=20 > + @param[in] MpServices MP_SERVICES structure. >=20 > + >=20 > + @retval Return the logical processor number. >=20 > +**/ >=20 > +UINT32 >=20 > +CpuCacheInfoWhoAmI ( >=20 > + IN MP_SERVICES MpServices >=20 > + ); >=20 > + >=20 > +/** >=20 > + Get the total number of logical processors in the platform. >=20 > + >=20 > + @param[in] MpServices MP_SERVICES structure. >=20 > + >=20 > + @retval Return the total number of logical processors. >=20 > +**/ >=20 > +UINT32 >=20 > +CpuCacheInfoGetNumberOfProcessors ( >=20 > + IN MP_SERVICES MpServices >=20 > + ); >=20 > +#endif >=20 > diff --git a/UefiCpuPkg/Library/CpuCacheInfoLib/PeiCpuCacheInfoLib.inf > b/UefiCpuPkg/Library/CpuCacheInfoLib/PeiCpuCacheInfoLib.inf > new file mode 100644 > index 000000000000..c8aa33c95a8f > --- /dev/null > +++ b/UefiCpuPkg/Library/CpuCacheInfoLib/PeiCpuCacheInfoLib.inf > @@ -0,0 +1,43 @@ > +## @file >=20 > +# CPU Cache Info Library instance for PEI module. >=20 > +# >=20 > +# Provides cache info for each package, core type, cache level and cach= e type. >=20 > +# >=20 > +# Copyright (c) 2020, Intel Corporation. All rights reserved.
>=20 > +# >=20 > +# SPDX-License-Identifier: BSD-2-Clause-Patent >=20 > +# >=20 > +## >=20 > + >=20 > +[Defines] >=20 > + INF_VERSION =3D 0x00010005 >=20 > + BASE_NAME =3D PeiCpuCacheInfoLib >=20 > + FILE_GUID =3D CFEE2DBE-53B2-4916-84CA-0BA83C3DDA6= E >=20 > + MODULE_TYPE =3D PEIM >=20 > + VERSION_STRING =3D 1.0 >=20 > + LIBRARY_CLASS =3D CpuCacheInfoLib|PEIM >=20 > + MODULE_UNI_FILE =3D CpuCacheInfoLib.uni >=20 > + >=20 > +[Sources] >=20 > + InternalCpuCacheInfoLib.h >=20 > + CpuCacheInfoLib.c >=20 > + PeiCpuCacheInfoLib.c >=20 > + >=20 > +[Packages] >=20 > + MdePkg/MdePkg.dec >=20 > + UefiCpuPkg/UefiCpuPkg.dec >=20 > + >=20 > +[LibraryClasses] >=20 > + BaseLib >=20 > + DebugLib >=20 > + BaseMemoryLib >=20 > + MemoryAllocationLib >=20 > + PeiServicesTablePointerLib >=20 > + >=20 > +[Ppis] >=20 > + gEdkiiPeiMpServices2PpiGuid >=20 > + >=20 > +[Pcd] >=20 > + >=20 > +[Depex] >=20 > + TRUE >=20 > diff --git a/UefiCpuPkg/UefiCpuPkg.dec b/UefiCpuPkg/UefiCpuPkg.dec > index d83c084467b3..a639ce5412e4 100644 > --- a/UefiCpuPkg/UefiCpuPkg.dec > +++ b/UefiCpuPkg/UefiCpuPkg.dec > @@ -56,6 +56,9 @@ [LibraryClasses.IA32, LibraryClasses.X64] > ## @libraryclass Provides function to support VMGEXIT processing. >=20 > VmgExitLib|Include/Library/VmgExitLib.h >=20 >=20 >=20 > + ## @libraryclass Provides function to get CPU cache information. >=20 > + CpuCacheInfoLib|Include/Library/CpuCacheInfoLib.h >=20 > + >=20 > [Guids] >=20 > gUefiCpuPkgTokenSpaceGuid =3D { 0xac05bf33, 0x995a, 0x4ed4, { 0xa= a, 0xb8, 0xef, 0x7a, 0xe8, 0xf, 0x5c, 0xb0 }} >=20 > gMsegSmramGuid =3D { 0x5802bce4, 0xeeee, 0x4e33, { 0xa= 1, 0x30, 0xeb, 0xad, 0x27, 0xf0, 0xe4, 0x39 }} >=20 > diff --git a/UefiCpuPkg/UefiCpuPkg.dsc b/UefiCpuPkg/UefiCpuPkg.dsc > index b2b6d78a71b0..5834eafaa200 100644 > --- a/UefiCpuPkg/UefiCpuPkg.dsc > +++ b/UefiCpuPkg/UefiCpuPkg.dsc > @@ -75,6 +75,7 @@ [LibraryClasses.common.PEIM] > LockBoxLib|MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxPeiLib.inf >=20 > MpInitLib|UefiCpuPkg/Library/MpInitLib/PeiMpInitLib.inf >=20 > RegisterCpuFeaturesLib|UefiCpuPkg/Library/RegisterCpuFeaturesLib/PeiRe= gisterCpuFeaturesLib.inf >=20 > + CpuCacheInfoLib|UefiCpuPkg/Library/CpuCacheInfoLib/PeiCpuCacheInfoLib.= inf >=20 >=20 >=20 > [LibraryClasses.IA32.PEIM, LibraryClasses.X64.PEIM] >=20 > PeiServicesTablePointerLib|MdePkg/Library/PeiServicesTablePointerLibId= t/PeiServicesTablePointerLibIdt.inf >=20 > @@ -86,6 +87,7 @@ [LibraryClasses.common.DXE_DRIVER] > CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCp= uExceptionHandlerLib.inf >=20 > MpInitLib|UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf >=20 > RegisterCpuFeaturesLib|UefiCpuPkg/Library/RegisterCpuFeaturesLib/DxeRe= gisterCpuFeaturesLib.inf >=20 > + CpuCacheInfoLib|UefiCpuPkg/Library/CpuCacheInfoLib/DxeCpuCacheInfoLib.= inf >=20 >=20 >=20 > [LibraryClasses.common.DXE_SMM_DRIVER] >=20 > SmmServicesTableLib|MdePkg/Library/SmmServicesTableLib/SmmServicesTabl= eLib.inf >=20 > @@ -109,6 +111,8 @@ [Components] > UefiCpuPkg/Library/CpuTimerLib/BaseCpuTimerLib.inf >=20 > UefiCpuPkg/Library/CpuTimerLib/DxeCpuTimerLib.inf >=20 > UefiCpuPkg/Library/CpuTimerLib/PeiCpuTimerLib.inf >=20 > + UefiCpuPkg/Library/CpuCacheInfoLib/PeiCpuCacheInfoLib.inf >=20 > + UefiCpuPkg/Library/CpuCacheInfoLib/DxeCpuCacheInfoLib.inf >=20 >=20 >=20 > [Components.IA32, Components.X64] >=20 > UefiCpuPkg/CpuDxe/CpuDxe.inf >=20 > -- > 2.28.0.windows.1