From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mga09.intel.com (mga09.intel.com [134.134.136.24]) by mx.groups.io with SMTP id smtpd.web10.3421.1610510508490152732 for ; Tue, 12 Jan 2021 20:01:48 -0800 Authentication-Results: mx.groups.io; dkim=pass header.i=@intel.onmicrosoft.com header.s=selector2-intel-onmicrosoft-com header.b=ntHEjMbn; spf=pass (domain: intel.com, ip: 134.134.136.24, mailfrom: ray.ni@intel.com) IronPort-SDR: XuI2fBqsBH3r41+wlo2p8Q2A7T+hZ4JlvSQjt8lkVlKXaHPtUAE7w0AZf7uIjLoE4K6Y+T8BMn KZe7BmrjsZJg== X-IronPort-AV: E=McAfee;i="6000,8403,9862"; a="178294879" X-IronPort-AV: E=Sophos;i="5.79,343,1602572400"; d="scan'208";a="178294879" Received: from orsmga001.jf.intel.com ([10.7.209.18]) by orsmga102.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 12 Jan 2021 20:01:48 -0800 IronPort-SDR: cxMBpDJXe33AAKO6Kq1jAgAiSbfH2ZNFHPHbFg2m4dsNVqhtfyhqPmoEJ91mzZ8iR9TWjNHjc7 v+TzdKFOye7Q== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.79,343,1602572400"; d="scan'208";a="424413331" Received: from orsmsx605.amr.corp.intel.com ([10.22.229.18]) by orsmga001.jf.intel.com with ESMTP; 12 Jan 2021 20:01:47 -0800 Received: from orsmsx610.amr.corp.intel.com (10.22.229.23) by ORSMSX605.amr.corp.intel.com (10.22.229.18) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.1713.5; Tue, 12 Jan 2021 20:01:47 -0800 Received: from orsmsx603.amr.corp.intel.com (10.22.229.16) by ORSMSX610.amr.corp.intel.com (10.22.229.23) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.1713.5; Tue, 12 Jan 2021 20:01:47 -0800 Received: from ORSEDG601.ED.cps.intel.com (10.7.248.6) 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 via Frontend Transport; Tue, 12 Jan 2021 20:01:47 -0800 Received: from NAM12-BN8-obe.outbound.protection.outlook.com (104.47.55.171) by edgegateway.intel.com (134.134.137.102) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.1.1713.5; Tue, 12 Jan 2021 20:01:46 -0800 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=Jk6ZxkPnCCyBQ/TlOjcQ8AtSJDg10Iobmq6uB+RIfnWp8wHqxeX1KnVy/446rlhxKDD5vlZJ7PHXrK3V34LqVUIw30ooSc8batjEDoJNdS2mKrYwiEPGfoPSZ6Xbeqe2qFu3uKmYCR3p8N+qcU4yGIm8lizffntXpzCIgwuCzOtWiCVMZ88GtzRQ3dwo0HDFtURd5BWpwyb33GhcuBHbyE2gIVplRAEQ53sdvu/RM18cQreHBl+xQt+9HjybBvu7E9tywAlXM61Vh29A6tSp/Ppr06PrsaSMqljUHC3JZrpmwl8wsK98Ogclhrb5UYC4do3/WRBF2CgXSaBNp0bDLA== 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=c7eTo0sJ97oBYdXpbKPRJHlkZq3tq6J76NIjLiWxshQ=; b=LePy56CqZ61dejckSFhgZ6Ps5q9rB0pttzB8ahijbLI7S4hjDHMk+1AcgT/AuIBpHu/6Ost9pdKpaP9qzPoTEy2lEK5LY67TbwYwlXTH00exK8juN66mCP7ZSvshcZ4VsMXLL3rEhs3UMQw/Bo5Ks5IJEKZO1gE4xIfah3vDEe6bUgYm+QtCwBlk12rDE9nrPYwXhAwFlH4uzN0E3FFu+10zuyU0yHeXLbYfn6ybecA55GBGJsau27CYeGh1DKPMeb/4IK0dTkoIKJ/1NlH2+o1i90PqthFIoz3CGxiLoQpX4/AXgHdPF8vZOg0j5FGj90GuYlIg5ocYkVIXHoCjJQ== 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=c7eTo0sJ97oBYdXpbKPRJHlkZq3tq6J76NIjLiWxshQ=; b=ntHEjMbnXLXaEr0cVTu2bDhFTz5wUh/4q+Z07UJzjFGlj7rF9T3cSTClvk2VD9e/xZLonSQnJCfNOX0lV+hxvBJQ/uPLHhq+MNYWjvrvxudZZWJ4Z9d5H/MJPeFHMHIrfBO7F2zm7Qf5GGYT/A6y6I3G7oRLT75jM/gcx0yIzMY= Received: from CO1PR11MB4930.namprd11.prod.outlook.com (2603:10b6:303:9b::11) by MW3PR11MB4761.namprd11.prod.outlook.com (2603:10b6:303:53::15) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3763.9; Wed, 13 Jan 2021 04:01:44 +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.3742.012; Wed, 13 Jan 2021 04:01:44 +0000 From: "Ni, Ray" To: "Lou, Yun" , "devel@edk2.groups.io" CC: "Dong, Eric" , Laszlo Ersek , "Kumar, Rahul1" Subject: Re: [PATCH v5 2/2] UefiCpuPkg/CpuCacheInfoLib: Add new CpuCacheInfoLib. Thread-Topic: [PATCH v5 2/2] UefiCpuPkg/CpuCacheInfoLib: Add new CpuCacheInfoLib. Thread-Index: AQHW5KRwvwHrERdA90+LzfnS9qbEFKok93Bw Date: Wed, 13 Jan 2021 04:01:44 +0000 Message-ID: References: <20210107032246.3101-1-yun.lou@intel.com> <20210107032246.3101-2-yun.lou@intel.com> In-Reply-To: <20210107032246.3101-2-yun.lou@intel.com> Accept-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: 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: [192.198.147.194] x-ms-publictraffictype: Email x-ms-office365-filtering-correlation-id: 6461a0b0-813a-46e2-5add-08d8b777f113 x-ms-traffictypediagnostic: MW3PR11MB4761: x-ms-exchange-transport-forked: True x-microsoft-antispam-prvs: x-ms-oob-tlc-oobclassifiers: OLM:4941; x-ms-exchange-senderadcheck: 1 x-microsoft-antispam: BCL:0; x-microsoft-antispam-message-info: lf6hDXdch0pLhLfgQ8WJSkFo4LhfMxJ6tG1og+ABZjW2IGOrB1ymOEfgha2vwZuJ5rRHgO5trHowKX+gIJaPhJZ3e41VuwdPRJgiXyiiwy739JOzQ6vRH13WfJjKVca4qL7/g/SCc7kcMDMqwoZFjCXLhxhvjtxlWo8djyGhN1MnBcbpjribYotXhQ5oAyFK2vBZBscrpTd6E10v2EjkGNYDQ5oJJS9uzcKoOuiF6+I9FqKppMHfX+GUTobF/U18zevIRSWzDSg3C0hpYIe4nseO/vwZ0ZaohBOoHv5eoH+IO2u/uQM2VUYJwQBPCXDwx0ixdVB3cbDq5CrrGnK41QuUfXQj6LNrgTao4pQA7Mi5ZWwl+DU70FunCLsFHMxZgJS+zllNXESnob7mGDI9VReZxaDKnZ+nW/QBnSErpPhW5zvMXDHUJOPWmZfiz+RN7Ga8MsTXftqqJ6f7U2xxCQ== 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)(136003)(346002)(39860400002)(366004)(376002)(396003)(30864003)(86362001)(110136005)(478600001)(64756008)(5660300002)(2906002)(19627235002)(54906003)(8936002)(83380400001)(66556008)(9686003)(52536014)(55016002)(4326008)(53546011)(6506007)(76116006)(107886003)(33656002)(8676002)(71200400001)(186003)(966005)(66446008)(66946007)(316002)(26005)(7696005)(66476007)(559001)(579004);DIR:OUT;SFP:1102; x-ms-exchange-antispam-messagedata: =?us-ascii?Q?Eh4ii3TH4UXSSUEF5/uFH3AP9A0ARdf08TbVWicFY9Wygb932ce6KSk0BTlu?= =?us-ascii?Q?MxF/roCqXUnPcepyf376AON1j/8oAFdm1aP9aAT/dOtpVO0dIDa6F31GY/qw?= =?us-ascii?Q?7ysHo1M9j9iDorNrTKiHMWYJUrqqQfbmSF+rBih7/bGkoFymXRizV6xs+MWz?= =?us-ascii?Q?dW8jqUXt6+wVTU7euvfHJtGrZaiiDXzGabBfan/DN1v8wOqJfWLbaCMZAoFc?= =?us-ascii?Q?zluPc18DUA8IhwqnVfhgxHtLOZNO1W5xhYASkchTfOhcovwCpKYVhzVa0gZ5?= =?us-ascii?Q?vlc3CJEIOlK5R/LiAKlsyzjjNypcdrf5i1fIPFVCYHls+x4hrfDrpwhgKcjo?= =?us-ascii?Q?tRGJPZTR33/a6lowlVwHP01fducTliW74wN/kxQ3L8pl2glKW8Sd+Db3JflH?= =?us-ascii?Q?ibuoXh0o0db39Oi9wlv71ng78TKo6r4uCr16N1a2dBYBrpK5+AN3kNBJTlkJ?= =?us-ascii?Q?5ya1ulP5837X+O0wHJAIR7wwaN7xtHWhvObkc3NlsLzF46Y57LfF2J01LOAz?= =?us-ascii?Q?mNWmbm/FmJDaXalL3CstToA8HaMV3GxbcmDl/scoKa9oWzHQxqTWWZ+rKB2b?= =?us-ascii?Q?3tYIH8AMm8jf3YBrVklcglfZ9CCL1jjRWsZk23IqVaBOyW5H9PdQYuY9oFvT?= =?us-ascii?Q?77BajckzinGfOHQhWpvOeNUKJnPqWawd+RxszNiUhTpwOCgCRmkCKfQT3lLE?= =?us-ascii?Q?9fST8oTC1umtj7reuVUSAuG1r+3HxQSGExdi5idN1dq/QTJPnCbqiy7o3MtX?= =?us-ascii?Q?JGeoAZUUM4Be/PgKGLDjXObxXDFRWBkImjSnzRxbPiSKdqBdFECsx3rWJS6a?= =?us-ascii?Q?qxdgXjCi4TExsvVj+VJNIWVpGqwMq+jpQBtRnttsLnJganP/R3MaT7RpXorI?= =?us-ascii?Q?peWnjuWeTOW7vhDeN3hapAyotjkuv+GFatM1NM+5Q0qaBHcWB0aCj3KQyFV7?= =?us-ascii?Q?UiDTF5ET1TZM5frggJOv+c4wcRReYstI0G/ksmBdCNlxVUoMiskWJ9I8/Imf?= =?us-ascii?Q?wcjh?= 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: 6461a0b0-813a-46e2-5add-08d8b777f113 X-MS-Exchange-CrossTenant-originalarrivaltime: 13 Jan 2021 04:01:44.5458 (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: oaYVHpu9T7mPh3EMx+oFnAJ7iAMMx9aHuR93RJix7h1etOx3gYnu/oUa2walgF7ii7UIRtJ8yBvTwl+AlT/+6w== X-MS-Exchange-Transport-CrossTenantHeadersStamped: MW3PR11MB4761 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 Laszlo, Have you given Acked-by or Reviewed-by before? I cannot find it. This version is good to me. I will create pull request once MdePkg maintain= ers=20 and you approve. Thanks, Ray > -----Original Message----- > From: Lou, Yun > Sent: Thursday, January 7, 2021 11:23 AM > To: devel@edk2.groups.io > Cc: Lou, Yun ; Ni, Ray ; Dong, Eric > ; Laszlo Ersek ; Kumar, Rahul1 > > Subject: [PATCH v5 2/2] UefiCpuPkg/CpuCacheInfoLib: Add new > CpuCacheInfoLib. >=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 | 440 > ++++++++++++++++++++ > 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, 1022 insertions(+) >=20 > diff --git a/UefiCpuPkg/Library/CpuCacheInfoLib/CpuCacheInfoLib.c > b/UefiCpuPkg/Library/CpuCacheInfoLib/CpuCacheInfoLib.c > new file mode 100644 > index 000000000000..ec506cda471c > --- /dev/null > +++ b/UefiCpuPkg/Library/CpuCacheInfoLib/CpuCacheInfoLib.c > @@ -0,0 +1,440 @@ > +/** @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, > CpuCacheInfo[Index].CacheLevel, >=20 > + CpuCacheInfo[Index].CacheType, CpuCacheInfo[Index].CacheWays, > CpuCacheInfo[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; > ProcessorIndex++) { >=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; > ProcessorIndex++) { >=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 > instructions. >=20 > + >=20 > + @param[in] Buffer The pointer to private data buffer. >=20 > +**/ >=20 > +VOID >=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 > * ProcessorIndex]; >=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_LEAF, > &NativeModelIdAndCoreTypeEax.Uint32, NULL, NULL, NULL); >=20 > + Context->ProcessorInfo[ProcessorIndex].CoreType =3D (UINT8) > NativeModelIdAndCoreTypeEax.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)CacheParamEax.Bits.CacheLevel; >=20 > + CacheData[CacheParamLeafIndex].CacheType =3D > (UINT8)CacheParamEax.Bits.CacheType; >=20 > + CacheData[CacheParamLeafIndex].CacheWays =3D > (UINT16)CacheParamEbx.Bits.Ways; >=20 > + CacheData[CacheParamLeafIndex].CacheShareBits =3D > (UINT16)CacheParamEax.Bits.MaximumAddressableIdsForLogicalProcessors; >=20 > + CacheData[CacheParamLeafIndex].CacheSizeinKB =3D > (CacheParamEbx.Bits.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, > NumberOfProcessors, 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_NUM_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].ApicId & > ~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; > CacheInfoIndex++) { >=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[Index].CacheLevel && >=20 > + LocalCacheInfo[CacheInfoIndex].CacheType =3D=3D > CacheData[Index].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[Index].CacheLevel; >=20 > + LocalCacheInfo[LocalCacheInfoCount].CacheType =3D > CacheData[Index].CacheType; >=20 > + LocalCacheInfo[LocalCacheInfoCount].CacheWays =3D > CacheData[Index].CacheWays; >=20 > + LocalCacheInfo[LocalCacheInfoCount].CacheSizeinKB =3D > CacheData[Index].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) * > LocalCacheInfoCount); >=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 * > sizeof (*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 > response 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 > CpuCacheInfoCount contains the value >=20 > + greater than zero. >=20 > + @retval EFI_UNSUPPORTED Processor does not support > CPUID_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.MpServices); >=20 > + >=20 > + // >=20 > + // Initialize COLLECT_CPUID_CACHE_DATA_CONTEXT.ProcessorInfo. >=20 > + // >=20 > + Context.ProcessorInfo =3D AllocatePages (EFI_SIZE_TO_PAGES > (NumberOfProcessors * 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 > (NumberOfProcessors * sizeof (*Context.ProcessorInfo))); >=20 > + return EFI_OUT_OF_RESOURCES; >=20 > + } >=20 > + >=20 > + ZeroMem (Context.CacheData, CacheDataCount * sizeof > (*Context.CacheData)); >=20 > + >=20 > + // >=20 > + // Collect Package ID and APIC ID of all processors. >=20 > + // >=20 > + for (ProcessorIndex =3D 0; ProcessorIndex < NumberOfProcessors; > ProcessorIndex++) { >=20 > + CpuCacheInfoGetProcessorInfo (Context.MpServices, ProcessorIndex, > &ProcessorInfo); >=20 > + Context.ProcessorInfo[ProcessorIndex].Package =3D > ProcessorInfo.Location.Package; >=20 > + Context.ProcessorInfo[ProcessorIndex].ApicId =3D (UINT32) > ProcessorInfo.ProcessorId; >=20 > + } >=20 > + >=20 > + // >=20 > + // Wakeup all processors for CacheData(core type and cache data) colle= ction. >=20 > + // >=20 > + CpuCacheInfoStartupAllCPUs (Context.MpServices, > CpuCacheInfoCollectCoreAndCacheData, &Context); >=20 > + >=20 > + // >=20 > + // Collect CpuCacheInfo data from CacheData. >=20 > + // >=20 > + Status =3D CpuCacheInfoCollectCpuCacheInfoData (Context.CacheData, > Context.ProcessorInfo, NumberOfProcessors, CpuCacheInfo, > CpuCacheInfoCount); >=20 > + >=20 > + FreePages (Context.CacheData, EFI_SIZE_TO_PAGES (CacheDataCount * > sizeof (*Context.CacheData))); >=20 > + FreePages (Context.ProcessorInfo, EFI_SIZE_TO_PAGES > (NumberOfProcessors * 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_SERVICES_PROTOCOL is stored >=20 > + >=20 > + @retval EFI_SUCCESS EFI_MP_SERVICES_PROTOCOL interface is > returned >=20 > + @retval EFI_NOT_FOUND EFI_MP_SERVICES_PROTOCOL 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 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, > Procedure, 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, > &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.Protocol->GetNumberOfProcessors > (MpServices.Protocol, &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_SERVICES2_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, > &NumberOfProcessor, &NumberOfEnabledProcessor); >=20 > + ASSERT_EFI_ERROR (Status); >=20 > + >=20 > + return (UINT32)NumberOfProcessor; >=20 > +} >=20 > diff --git a/UefiCpuPkg/Include/Library/CpuCacheInfoLib.h > b/UefiCpuPkg/Include/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 > response 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 > CpuCacheInfoCount contains the value >=20 > + greater than zero. >=20 > + @retval EFI_UNSUPPORTED Processor does not support > CPUID_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_APPLICATION >=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 > CpuCacheInfoCollectCoreAndCacheData 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_SERVICES2_PPI or >=20 > + EFI_MP_SERVICES_PROTOCOL is stored >=20 > + >=20 > + @retval EFI_SUCCESS EDKII_PEI_MP_SERVICES2_PPI or > EFI_MP_SERVICES_PROTOCOL interface is returned >=20 > + @retval EFI_NOT_FOUND EDKII_PEI_MP_SERVICES2_PPI or > EFI_MP_SERVICES_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 >=20 > RegisterCpuFeaturesLib|UefiCpuPkg/Library/RegisterCpuFeaturesLib/PeiRegis= t > erCpuFeaturesLib.inf >=20 > + > CpuCacheInfoLib|UefiCpuPkg/Library/CpuCacheInfoLib/PeiCpuCacheInfoLib.inf >=20 >=20 >=20 > [LibraryClasses.IA32.PEIM, LibraryClasses.X64.PEIM] >=20 >=20 > PeiServicesTablePointerLib|MdePkg/Library/PeiServicesTablePointerLibIdt/P= eiS > ervicesTablePointerLibIdt.inf >=20 > @@ -86,6 +87,7 @@ [LibraryClasses.common.DXE_DRIVER] >=20 > CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpu > ExceptionHandlerLib.inf >=20 > MpInitLib|UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf >=20 >=20 > RegisterCpuFeaturesLib|UefiCpuPkg/Library/RegisterCpuFeaturesLib/DxeRegis= t > erCpuFeaturesLib.inf >=20 > + > CpuCacheInfoLib|UefiCpuPkg/Library/CpuCacheInfoLib/DxeCpuCacheInfoLib.inf >=20 >=20 >=20 > [LibraryClasses.common.DXE_SMM_DRIVER] >=20 >=20 > SmmServicesTableLib|MdePkg/Library/SmmServicesTableLib/SmmServicesTab > leLib.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