From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by mx.groups.io with SMTP id smtpd.web09.6757.1606809601853719936 for ; Tue, 01 Dec 2020 00:00:02 -0800 Authentication-Results: mx.groups.io; dkim=pass header.i=@intel.onmicrosoft.com header.s=selector2-intel-onmicrosoft-com header.b=pymmrHmM; spf=pass (domain: intel.com, ip: 134.134.136.65, mailfrom: ray.ni@intel.com) IronPort-SDR: X+6EGYwErUGCor0MqjbP+1eCuhlFMGv9P2T7bvUXSLhf19K5fBcjQf2TKr/UEWAam5Ljq/eXgD ynuFJrnILhbQ== X-IronPort-AV: E=McAfee;i="6000,8403,9821"; a="172884603" X-IronPort-AV: E=Sophos;i="5.78,383,1599548400"; d="scan'208";a="172884603" X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga007.fm.intel.com ([10.253.24.52]) by orsmga103.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 01 Dec 2020 00:00:00 -0800 IronPort-SDR: H4sABVLu+c0Wu5MGFOnu16DLLq+9RMdRuKD9VOY+9EIB1CySoYiynOjeQkQKM6TlA1DdvaIQ9b ZXBfitEa+CLA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.78,383,1599548400"; d="scan'208";a="315576876" Received: from orsmsx603.amr.corp.intel.com ([10.22.229.16]) by fmsmga007.fm.intel.com with ESMTP; 01 Dec 2020 00:00:00 -0800 Received: from orsmsx609.amr.corp.intel.com (10.22.229.22) 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; Mon, 30 Nov 2020 23:59:59 -0800 Received: from ORSEDG602.ED.cps.intel.com (10.7.248.7) by orsmsx609.amr.corp.intel.com (10.22.229.22) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.1713.5 via Frontend Transport; Mon, 30 Nov 2020 23:59:59 -0800 Received: from NAM11-CO1-obe.outbound.protection.outlook.com (104.47.56.168) by edgegateway.intel.com (134.134.137.103) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.1.1713.5; Mon, 30 Nov 2020 23:57:43 -0800 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=MNFmmHduUhVlubEyyncvL7moer06UnBGYjrhArdxkQX2fQpoRq9Ta+vSdBdU4LIzXynrC6d8/0CfxxAv3uR2RT3v2KpR3WFfbba/u6AYraeSLThQWSlbgdI8chRtjE20CfkO9LLC6MecrglKAAz4PMVnV8DTnnJiPoY2BKsj4bbhuE2lcmoMjhKS8va4HtcE+/RjLkq8yDA4mvc3e//VWfSPm8vJiYf7x+jeEw5SJM/8GTIq+RYc166x8tO6L/f81ko+uNQOWbTQzCMEP+eLtCrFclf7L49hDzrYloz02b0ycNeiQnai1lvf4c53FP/U3FXrX2LDYQa0PnTDUVtKBw== 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=iotD+k1RbeQjfKdBohq90X4fQ+8w59G3NnrNVLymJNA=; b=ddaYQGB7z/8+5kWIRX8wjPloWwp7PKth3CsSju/SqvN8Ew1R7cPNqxClqY/kmtKVIt6Uxr+SjgR5o84hprR6Er0UBA0gu0wC7bIywMjcCxhGK34lQ/oPbF5Opeg+/YPnyNpSH7yAwse10PpmB3G2/IwTJU4jX+cECR8FDF+YMTQfO9C5iR7B1lplK2lw8z8AzR1ljaIG084HbunVYTNEJnCpk3rrAz75cfEzx5ZGu89QzWwZtv8NvQYL7+3oLjYESjpV5XtV+9HLyovbunmGESOFclmQlN8zzeuWodKd+Ec6t0TRA+yod9qJak29UonjF5VqKPJxPr9g6uxSH2Ib3Q== 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=iotD+k1RbeQjfKdBohq90X4fQ+8w59G3NnrNVLymJNA=; b=pymmrHmMhAEMImheUJ0wkRySnmuSx8yOM6aZ/YlG+0sDKSRTO26zMvRGSAdajbtPUI/MN0Pi0wOEqgIKfgsnZWjlYhLvTlfsNh38h0dfxyjIAD+mqxHtUDcN23DgWlUB+JUvaECqDrh5niUvFc/HTAB67d2YQhmoz3BQ2cWwmNY= Received: from CO1PR11MB4930.namprd11.prod.outlook.com (2603:10b6:303:9b::11) by MWHPR11MB1776.namprd11.prod.outlook.com (2603:10b6:300:110::14) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3611.25; Tue, 1 Dec 2020 07:57:41 +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.3611.031; Tue, 1 Dec 2020 07:57:41 +0000 From: "Ni, Ray" To: "Lou, Yun" , "devel@edk2.groups.io" CC: "Dong, Eric" , Laszlo Ersek , "Kumar, Rahul1" Subject: Re: [PATCH v1 2/2] UefiCpuPkg/CpuCacheInfoLib: Add new CpuCacheInfoLib. Thread-Topic: [PATCH v1 2/2] UefiCpuPkg/CpuCacheInfoLib: Add new CpuCacheInfoLib. Thread-Index: AQHWvh0JIPs8BAOGYUu4zt0tSYa5aanhp5qw Date: Tue, 1 Dec 2020 07:57:41 +0000 Message-ID: References: <20201119023658.926-1-yun.lou@intel.com> <20201119023658.926-2-yun.lou@intel.com> In-Reply-To: <20201119023658.926-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: [192.198.147.215] x-ms-publictraffictype: Email x-ms-office365-filtering-correlation-id: 37be2fc4-7446-4139-dde8-08d895cec7a2 x-ms-traffictypediagnostic: MWHPR11MB1776: x-ms-exchange-transport-forked: True x-microsoft-antispam-prvs: x-ms-oob-tlc-oobclassifiers: OLM:2887; x-ms-exchange-senderadcheck: 1 x-microsoft-antispam: BCL:0; x-microsoft-antispam-message-info: 9G8oNBLxL28uZBRhwym+sQzh4Gc8t63yZFcD4z0h4CVPipdaLHNchTyfM/p30gNOcRJrmD5M8Ia/9SraqebX8NT++MnYWNI9IljL+g04t9tAuvrUG6mtRFRoytqSiwMy7Ru+GBD9KTiZdcl4t2/XzhogJhivcb4xq7tCLBHOVkYVabS6VTz1nMdDhoLKyTABcnmijcWSNBbKEONe+rKqdjuQOoeOAVlyErL6yqASb9DxXJ1HXwkMT/tGUMHkaG0ZUVbtfU7sFM4jQHavHm9jdCeGDNpipFFfj/R2ZbLHok1+lkUvRseDcagIxu6Ce0lm9PRJIv9wVHMf1GCGyMp4LA== 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)(376002)(136003)(396003)(346002)(366004)(39860400002)(5660300002)(83380400001)(2906002)(52536014)(8676002)(66476007)(66556008)(30864003)(64756008)(8936002)(66446008)(71200400001)(33656002)(66946007)(54906003)(4326008)(55016002)(186003)(86362001)(26005)(110136005)(9686003)(19627235002)(478600001)(107886003)(53546011)(6506007)(76116006)(7696005)(316002)(579004)(559001);DIR:OUT;SFP:1102; x-ms-exchange-antispam-messagedata: =?us-ascii?Q?KIoRsJj5+6h8LZdh7gs8JkgVm3XimIGTCEID4IJxXNGWu9PiYYdEH+UHfG4E?= =?us-ascii?Q?y2oBhnu0hU142KZWcK40XoV2apRELX3qqllqZ7dSmiljfCrjwVxs4OMVtjfN?= =?us-ascii?Q?Kr3rct1+1/CFQryuHcQOgl7cUhc4itxsL+woI94xfL3WvORYHBZlhVXXLRUv?= =?us-ascii?Q?ssm1eUXa3fNOdUgi41KTy9Hcx2a3VfpyI+peL2T7nK+QXZHPblBmpoCAh551?= =?us-ascii?Q?4XcufX1vx5HdVguj3tn3ko6sShp9T5yWSjYjmXBdFAqe0g1J4BDC7DCxPGs6?= =?us-ascii?Q?EojLZF1UEKMF31qKNME7YnrulwxFS9gVPYTD9S5qKxoMMUgycN5zLuDsdl6/?= =?us-ascii?Q?mEtax7cft7oMkDF2D8ldFGleltim10R5yyKNViZFLYU1xLpeme2YBUdDTNLD?= =?us-ascii?Q?8P0zzrCUEJR81IsAgjMi1a9CuHNYOHoYJ6bn9ZnmdPEgRlvpSbV7XGGDhB75?= =?us-ascii?Q?v5ijWHdqMvw1D34/6E13CSmzFbXDLKWWfBnk1h7+e6rQH6BKLF/jn8hJqhBe?= =?us-ascii?Q?m2nWxFCq/3SMPR5PpWqNqEvUQ4XMWSGZRJtXvg4vba0Nq7dGpy2sF5wurW7C?= =?us-ascii?Q?VYMeBe5dbo4zBx2fGUEdKabKm76H+McHmAE9P6/QbUgvnrYW9GuhdqmZ9mEN?= =?us-ascii?Q?dDzktsm4Y+7ljlPL9GGunWyiKA9/fZdC8Tbjzo/prhMez2gQLUlQYOiSz0Xk?= =?us-ascii?Q?ytwt1N1gNO9TMV7ldiqOKZc8U3IrUgGS9vsAn+YKPZphLjI05urAEg1x7utI?= =?us-ascii?Q?o9m/4nSfwCU5BhJYvdn2WFxW1iEJzsaZ3nxlitg8zAU1StzL9dMYTA1ZTwvi?= =?us-ascii?Q?IagypeXxGbYjWuG0RCyln2/k68virlEynSkDcKY7g6cycaLRtRRbowYto9MB?= =?us-ascii?Q?WYd8AOBVXnppPBHCrSFOaKeFBYw0gh+RPjYbURcaLXrWPo3nfY1B1M511hwd?= =?us-ascii?Q?6MECUUdZjnelz70OlX/NQ4rMJ+tUkDGVT0wZJtvDk7o=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: 37be2fc4-7446-4139-dde8-08d895cec7a2 X-MS-Exchange-CrossTenant-originalarrivaltime: 01 Dec 2020 07:57:41.6274 (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: /fovtMsFSJ8xZ1jh0FQu7w+gLyWd52vBpnAbwWhIV5PyfBga3+Vxx4e3RDhei8ZuDHU0udhx6ZzXGqzRztbl1Q== X-MS-Exchange-Transport-CrossTenantHeadersStamped: MWHPR11MB1776 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 1. CpuCacheInfoLib.h: Please use the same notation as what SDM is using. For example: "Value =3D = CPUID(1A).Eax[31:24].Coretype" -> "Value =3D CPUID.1Ah:EAX[31:24]" 2. DEBUG((DEBUG_ERROR, "[CacheInfoLib] NumberOfProcessor =3D 0x%x\n", Num= berOfProcessor)); Please use the proper debug level. For example, the above message shouldn't= use DEBUG_ERROR. And please make sure only print necessary messages. Above "NumberOfProcesso= r" can be removed. 3. Please always put a space after the function call. For example: CollectC= oreAndCacheDataForAll(&Context); I don't see a consistent rule in your code. 4. ZeroMem(Context.CpuidCacheData, EFI_PAGES_TO_SIZE(EFI_SIZE_TO_PAGES(Cp= uidCacheDataCount * sizeof(*Context.CpuidCacheData)))); Why use EFI_PAGES_TO_SIZE and EFI_SIZE_TO_PAGES? can both macros be removed= in above function call? 5. CollectCoreAndCacheDataForAll (&Context); This function calls to Pei/Dxe= CpuCacheInfoLib.c and then calls back to CollectCoreAndCacheData () in CpuC= acheInfoLib.c. Can you create a function CpuCacheInfoStartupAllCPUs(MpServices, Procedure,= Context) in Pei/DxeCpuCacheInfoLib.c? So that CollectCoreAndCacheDataForAll() can be written as below in CpuCache= InfoLib.c as a common function? { EFI_STATUS Status; MP_SERVICES MpServices; MpServices =3D Context->MpServices; Status =3D CpuCacheInfoStartupAllCPUs (MpServices, CollectCoreAndCacheDat= a, Context); ASSERT_EFI_ERROR(Status); } It makes code more readable. So, you also don't need to extern " CollectCoreAndCacheData" in Pei/DxeCpuC= acheInfoLib.c. 6. Context.CpuidCacheData =3D AllocatePages(EFI_SIZE_TO_PAGES(CpuidCacheD= ataCount * sizeof(*Context.CpuidCacheData))); Can you add more comments to describe the layout of the CpuidCacheData? 7. CpuidCacheData[CacheParamLeafNum].CacheSizeinKB =3D ((CacheParamEbx.= Bits.Ways + 1) * \ (CacheParamEbx.Bits.LinePartitions+1) * (CacheParamEbx.Bits.LineSiz= e+1) * (CacheParamEcx+1)) / 1024; Put before and after "+". Change "1024" with "SIZE_1KB". 8. ProcessorNum =3D GetCurrentProcessorNum (Context->MpServices); Please change the "GetCurrentProcessorNum" to "CpuCacheInfoWhoAmI". Please change all library internal function to add the prefix "CpuCacheInfo= " to avoid link error when some other modules also contains the same functi= on name. 9. GetNumberOfPackage ( You don't need Package0Existed flag. You could use a local variable Package= Count (initially 0. You rename Count to PackageCount) to help to collect al= l packages. The pseudo code is like below: for each CpuidCacheData[] for (PackageIndex =3D 0; PackageIndex < PackageCount; PackageIndex++) { if CpuidCacheData->Location.Package =3D=3D Package[PackageIndex] break; if (PackageIndex =3D=3D PackageCount) Package[PackageCount++] =3D CpuidCacheData->Location.Package ASSERT (PackageCount <=3D MAX_NUM_OF_PACKAGE) 10 GetNumberOfCoreTypePerPackage You could use the similar algorithm as above to avoid CoreType0Existed. 11. PrintCpuidCacheDataTable, PrintCpuCacheInfoTable Please call them inside DEBUG_CODE macro. 12. LIBRARY_CLASS =3D CpuCacheInfoLib|DXE_CORE DXE_DRIVE= R DXE_RUNTIME_DRIVER UEFI_APPLICATION UEFI_DRIVER LIBRARY_CLASS =3D CpuCacheInfoLib|PEI_CORE PEIM Please only list DXE_DRIVER, UEFI_APPLICATION, PEIM in INF. > -----Original Message----- > From: Lou, Yun > Sent: Thursday, November 19, 2020 10:37 AM > To: devel@edk2.groups.io > Cc: Lou, Yun ; Ni, Ray ; Dong, Eric > ; Laszlo Ersek ; Kumar, Rahul1 > > Subject: [PATCH v1 2/2] UefiCpuPkg/CpuCacheInfoLib: Add new > CpuCacheInfoLib. >=20 > This 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. >=20 > Signed-off-by: Jason Lou > Cc: Ray Ni > Cc: Eric Dong > Cc: Laszlo Ersek > Cc: Rahul Kumar > --- > UefiCpuPkg/Library/CpuCacheInfoLib/CpuCacheInfoLib.c | 602 > ++++++++++++++++++++ > UefiCpuPkg/Library/CpuCacheInfoLib/DxeCpuCacheInfoLib.c | 131 +++++ > UefiCpuPkg/Library/CpuCacheInfoLib/PeiCpuCacheInfoLib.c | 130 +++++ > UefiCpuPkg/Include/Library/CpuCacheInfoLib.h | 68 +++ > UefiCpuPkg/Library/CpuCacheInfoLib/CpuCacheInfoLib.uni | 15 + > UefiCpuPkg/Library/CpuCacheInfoLib/DxeCpuCacheInfoLib.inf | 43 ++ > UefiCpuPkg/Library/CpuCacheInfoLib/InternalCpuCacheInfoLib.h | 64 +++ > UefiCpuPkg/Library/CpuCacheInfoLib/PeiCpuCacheInfoLib.inf | 43 ++ > UefiCpuPkg/UefiCpuPkg.dec | 3 + > UefiCpuPkg/UefiCpuPkg.dsc | 4 + > 10 files changed, 1103 insertions(+) >=20 > diff --git a/UefiCpuPkg/Library/CpuCacheInfoLib/CpuCacheInfoLib.c > b/UefiCpuPkg/Library/CpuCacheInfoLib/CpuCacheInfoLib.c > new file mode 100644 > index 000000000000..e0cc6bbf7fa2 > --- /dev/null > +++ b/UefiCpuPkg/Library/CpuCacheInfoLib/CpuCacheInfoLib.c > @@ -0,0 +1,602 @@ > +/** @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 > + Defines the maximum count of Deterministic Cache Parameters Leaf of al= l > APs >=20 > + and BSP. >=20 > + To save boot time, skip starting up all APs to calculate each AP's cou= nt of >=20 > + Deterministic Cache Parameters Leaf, so use a definition instead. >=20 > + Anyway, definition value will be checked in CollectCoreAndCacheData > function. >=20 > +*/ >=20 > +#define MAX_NUM_OF_CACHE_PARAMS_LEAF 5 >=20 > + >=20 > +/* >=20 > + Defines the maximum count of Core Type of all BSP and APs in one > package. >=20 > + Core Type value comes from CPUID(1Ah).Eax[31:24].Coretype >=20 > +*/ >=20 > +#define MAX_NUM_OF_CORE_TYPE 256 >=20 > + >=20 > +/* >=20 > + Defines the maximum count of packages. >=20 > +*/ >=20 > +#define MAX_NUM_OF_PACKAGE 100 >=20 > + >=20 > +/** >=20 > + Get EFI_MP_SERVICES_PROTOCOL pointer. >=20 > + >=20 > + @retval Return MP_SERVICES structure. >=20 > +**/ >=20 > +MP_SERVICES >=20 > +GetMpServices ( >=20 > + VOID >=20 > + ); >=20 > + >=20 > +/** >=20 > + Collect core and cache information of all APs and BSP via CPUID > instructions. >=20 > + >=20 > + @param[in] Context The pointer to > COLLECT_CPUID_CACHE_DATA_CONTEXT structure. >=20 > +**/ >=20 > +VOID >=20 > +CollectCoreAndCacheDataForAll ( >=20 > + IN COLLECT_CPUID_CACHE_DATA_CONTEXT *Context >=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 > + >=20 > + @retval Return EFI_PROCESSOR_INFORMATION structure of requested > logical processors. >=20 > +**/ >=20 > +EFI_PROCESSOR_INFORMATION >=20 > +GetCurrentProcessorInfo ( >=20 > + IN MP_SERVICES MpServices, >=20 > + IN UINTN ProcessorNum >=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 > +GetCurrentProcessorNum ( >=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 > +GetNumberOfProcessor ( >=20 > + IN MP_SERVICES MpServices >=20 > + ); >=20 > + >=20 > +/** >=20 > + Print CpuidCacheData array. >=20 > + >=20 > + @param[in] CpuidCacheData Pointer to the CpuidCacheData array. >=20 > + @param[in] CpuidCacheDataCount The length of CpuidCacheData array. >=20 > + >=20 > +**/ >=20 > +VOID >=20 > +PrintCpuidCacheDataTable ( >=20 > + IN CPUID_CACHE_DATA *CpuidCacheData, >=20 > + IN UINTN CpuidCacheDataCount >=20 > + ) >=20 > +{ >=20 > + UINTN Index; >=20 > + >=20 > + DEBUG((DEBUG_ERROR, "+-------+----------------------------------------= ------------------ > --------------+\n")); >=20 > + DEBUG((DEBUG_ERROR, "| Index | ApicId (Pkg / Core / Thread) CoreType > Level Type ShareBits SizeinKB |\n")); >=20 > + DEBUG((DEBUG_ERROR, "+-------+----------------------------------------= ------------------ > --------------+\n")); >=20 > + >=20 > + for (Index =3D 0; Index < CpuidCacheDataCount; Index++) { >=20 > + if (Index % MAX_NUM_OF_CACHE_PARAMS_LEAF =3D=3D 0) { >=20 > + DEBUG((DEBUG_ERROR, "|*")); >=20 > + } else { >=20 > + DEBUG((DEBUG_ERROR, "| ")); >=20 > + } >=20 > + >=20 > + DEBUG((DEBUG_ERROR, "%4x | %4x %4x /%4x > / %4x %2x %2x %2x %4x %8x |\n", Index, \ >=20 > + CpuidCacheData[Index].ApicId, > CpuidCacheData[Index].Location.Package, > CpuidCacheData[Index].Location.Core, \ >=20 > + CpuidCacheData[Index].Location.Thread, > CpuidCacheData[Index].CoreType, CpuidCacheData[Index].CacheLevel, \ >=20 > + CpuidCacheData[Index].CacheType, > CpuidCacheData[Index].CacheShareBits, > CpuidCacheData[Index].CacheSizeinKB)); >=20 > + } >=20 > + >=20 > + DEBUG((DEBUG_ERROR, "+-------+----------------------------------------= ------------------ > --------------+\n")); >=20 > +} >=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 > +PrintCpuCacheInfoTable ( >=20 > + IN CPU_CACHE_INFO *CpuCacheInfo, >=20 > + IN UINTN CpuCacheInfoCount >=20 > + ) >=20 > +{ >=20 > + UINTN Index; >=20 > + >=20 > + DEBUG((DEBUG_ERROR, "+-------+----------------------------------------= ------------------ > ----------+\n")); >=20 > + DEBUG((DEBUG_ERROR, "| Index | Packge CoreType CacheLevel > CacheType CacheSizeinKB CacheCount |\n")); >=20 > + DEBUG((DEBUG_ERROR, "+-------+----------------------------------------= ------------------ > ----------+\n")); >=20 > + >=20 > + for (Index =3D 0; Index < CpuCacheInfoCount; Index++) { >=20 > + DEBUG((DEBUG_ERROR, "| %4x > | %4x %2x %2x %2x %8x %4x |\n", In= dex, \ >=20 > + CpuCacheInfo[Index].Package, CpuCacheInfo[Index].CoreType, > CpuCacheInfo[Index].CacheLevel, \ >=20 > + CpuCacheInfo[Index].CacheType, CpuCacheInfo[Index].CacheSizeinKB= , > CpuCacheInfo[Index].CacheCount)); >=20 > + } >=20 > + >=20 > + DEBUG((DEBUG_ERROR, "+-------+----------------------------------------= ------------------ > ----------+\n")); >=20 > +} >=20 > + >=20 > +/** >=20 > + Get the total number of package in the platform. >=20 > + >=20 > + @param[in] CpuidCacheData Pointer to the CpuidCacheData array. >=20 > + @param[in] CpuidCacheDataCount The length of CpuidCacheData array. >=20 > + >=20 > + @retval Return the total number of package in the platform. >=20 > +**/ >=20 > +UINT32 >=20 > +GetNumberOfPackage ( >=20 > + IN CPUID_CACHE_DATA *CpuidCacheData, >=20 > + IN UINTN CpuidCacheDataCount >=20 > + ) >=20 > +{ >=20 > + UINTN ProcessorNum; >=20 > + UINTN PackageIndex; >=20 > + UINT32 Package[MAX_NUM_OF_PACKAGE]; >=20 > + BOOLEAN Package0Existed; >=20 > + UINTN Count; >=20 > + CPUID_CACHE_DATA *CurrentCpuidCacheData; >=20 > + >=20 > + // >=20 > + // Package array is empty. >=20 > + // >=20 > + Count =3D 0; >=20 > + Package0Existed =3D FALSE; >=20 > + ZeroMem(Package, sizeof(Package)); >=20 > + >=20 > + for (ProcessorNum =3D 0; ProcessorNum * > MAX_NUM_OF_CACHE_PARAMS_LEAF < CpuidCacheDataCount; > ProcessorNum++) { >=20 > + CurrentCpuidCacheData =3D &CpuidCacheData[ProcessorNum * > MAX_NUM_OF_CACHE_PARAMS_LEAF]; >=20 > + >=20 > + // >=20 > + // If package value is the same as default value of Package array. >=20 > + // We can not consider this value has already existed in the Package > array. >=20 > + // >=20 > + if (CurrentCpuidCacheData->Location.Package =3D=3D 0) { >=20 > + if (!Package0Existed) { >=20 > + Package0Existed =3D TRUE; >=20 > + Count++; >=20 > + ASSERT(Count <=3D MAX_NUM_OF_PACKAGE); >=20 > + } >=20 > + continue; >=20 > + } >=20 > + >=20 > + // >=20 > + // For the Package has already existed in Package array, break out t= he > loop. >=20 > + // >=20 > + for (PackageIndex =3D 0; PackageIndex < MAX_NUM_OF_PACKAGE; > PackageIndex++) { >=20 > + if (CurrentCpuidCacheData->Location.Package =3D=3D Package[Package= Index]) > { >=20 > + break; >=20 > + } >=20 > + } >=20 > + >=20 > + // >=20 > + // For the new type, save it in CoreType array. >=20 > + // >=20 > + if (PackageIndex =3D=3D MAX_NUM_OF_PACKAGE) { >=20 > + Package[Count++] =3D CurrentCpuidCacheData->Location.Package; >=20 > + ASSERT(Count <=3D MAX_NUM_OF_PACKAGE); >=20 > + } >=20 > + } >=20 > + >=20 > + return (UINT32)Count; >=20 > +} >=20 > + >=20 > +/** >=20 > + Get the number of CoreType of requested package. >=20 > + >=20 > + @param[in] CpuidCacheData Pointer to the CpuidCacheData array. >=20 > + @param[in] CpuidCacheDataCount The length of CpuidCacheData array. >=20 > + @param[in] Package The requested package number. >=20 > + >=20 > + @retval Return the number of CoreType of requested package. >=20 > +**/ >=20 > +UINT8 >=20 > +GetNumberOfCoreTypePerPackage ( >=20 > + IN CPUID_CACHE_DATA *CpuidCacheData, >=20 > + IN UINTN CpuidCacheDataCount, >=20 > + IN UINTN Package >=20 > + ) >=20 > +{ >=20 > + UINTN ProcessorNum; >=20 > + UINTN CoreTypeIndex; >=20 > + UINT8 CoreType[MAX_NUM_OF_CORE_TYPE]; >=20 > + BOOLEAN CoreType0Existed; >=20 > + UINTN Count; >=20 > + CPUID_CACHE_DATA *CurrentCpuidCacheData; >=20 > + >=20 > + // >=20 > + // CoreType array is empty. >=20 > + // >=20 > + Count =3D 0; >=20 > + CoreType0Existed =3D FALSE; >=20 > + ZeroMem(CoreType, sizeof(CoreType)); >=20 > + >=20 > + for (ProcessorNum =3D 0; ProcessorNum * > MAX_NUM_OF_CACHE_PARAMS_LEAF < CpuidCacheDataCount; > ProcessorNum++) { >=20 > + CurrentCpuidCacheData =3D &CpuidCacheData[ProcessorNum * > MAX_NUM_OF_CACHE_PARAMS_LEAF]; >=20 > + >=20 > + if (CurrentCpuidCacheData->Location.Package !=3D Package) { >=20 > + continue; >=20 > + >=20 > + // >=20 > + // If the type value is the same as default value of CoreType array. >=20 > + // We can not consider this value has already existed in the CoreTyp= e > array. >=20 > + // >=20 > + } else if (CurrentCpuidCacheData->CoreType =3D=3D 0) { >=20 > + if (!CoreType0Existed) { >=20 > + CoreType0Existed =3D TRUE; >=20 > + Count++; >=20 > + ASSERT(Count <=3D MAX_NUM_OF_CORE_TYPE); >=20 > + } >=20 > + continue; >=20 > + } >=20 > + >=20 > + // >=20 > + // For the type has already existed in CoreType array, break out the= loop. >=20 > + // >=20 > + for (CoreTypeIndex =3D 0; CoreTypeIndex < MAX_NUM_OF_CORE_TYPE; > CoreTypeIndex++) { >=20 > + if (CurrentCpuidCacheData->CoreType =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 MAX_NUM_OF_CORE_TYPE) { >=20 > + CoreType[Count++] =3D CurrentCpuidCacheData->CoreType; >=20 > + ASSERT(Count <=3D MAX_NUM_OF_CORE_TYPE); >=20 > + } >=20 > + } >=20 > + >=20 > + return (UINT8)Count; >=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 > +CollectCoreAndCacheData ( >=20 > + IN OUT VOID *Buffer >=20 > + ) >=20 > +{ >=20 > + UINTN ProcessorNum; >=20 > + UINT32 CpuidMaxInput; >=20 > + UINT8 CoreType; >=20 > + UINT8 CacheParamLeafNum; >=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 *CpuidCacheData; >=20 > + >=20 > + Context =3D (COLLECT_CPUID_CACHE_DATA_CONTEXT *)Buffer; >=20 > + >=20 > + ProcessorNum =3D GetCurrentProcessorNum (Context->MpServices); >=20 > + >=20 > + CpuidCacheData =3D &Context- > >CpuidCacheData[MAX_NUM_OF_CACHE_PARAMS_LEAF * ProcessorNum]; >=20 > + >=20 > + AsmCpuid (CPUID_SIGNATURE, &CpuidMaxInput, NULL, NULL, NULL); >=20 > + >=20 > + // >=20 > + // get CoreType if CPUID_HYBRID_INFORMATION leaf is supported. >=20 > + // >=20 > + 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 > + CoreType =3D (UINT8)NativeModelIdAndCoreTypeEax.Bits.CoreType; >=20 > + } >=20 > + >=20 > + // >=20 > + // cache hierarchy starts with an index value of 0. >=20 > + // >=20 > + CacheParamLeafNum =3D 0; >=20 > + >=20 > + while (CacheParamLeafNum !=3D MAX_NUM_OF_CACHE_PARAMS_LEAF) { >=20 > + AsmCpuidEx(CPUID_CACHE_PARAMS, CacheParamLeafNum, > &CacheParamEax.Uint32, &CacheParamEbx.Uint32, &CacheParamEcx, NULL); >=20 > + >=20 > + if (CacheParamEax.Bits.CacheType =3D=3D 0) { >=20 > + break; >=20 > + } >=20 > + >=20 > + CpuidCacheData[CacheParamLeafNum].CoreType =3D CoreType; >=20 > + CpuidCacheData[CacheParamLeafNum].CacheLevel =3D > (UINT8)CacheParamEax.Bits.CacheLevel; >=20 > + CpuidCacheData[CacheParamLeafNum].CacheType =3D > (UINT8)CacheParamEax.Bits.CacheType; >=20 > + CpuidCacheData[CacheParamLeafNum].CacheShareBits =3D > (UINT16)CacheParamEax.Bits.MaximumAddressableIdsForLogicalProcessors; >=20 > + CpuidCacheData[CacheParamLeafNum].CacheSizeinKB =3D > ((CacheParamEbx.Bits.Ways + 1) * \ >=20 > + (CacheParamEbx.Bits.LinePartitions+1) * > (CacheParamEbx.Bits.LineSize+1) * (CacheParamEcx+1)) / 1024; >=20 > + >=20 > + ASSERT(CacheParamLeafNum !=3D MAX_NUM_OF_CACHE_PARAMS_LEAF); >=20 > + CacheParamLeafNum++; >=20 > + } >=20 > +} >=20 > + >=20 > +/** >=20 > + Collect processor location information of all logical processors via > MpServices. >=20 > + >=20 > + @param[in] Context The pointer to > COLLECT_CPUID_CACHE_DATA_CONTEXT structure. >=20 > + @param[in] NumberOfProcessor The total number of logical processors > in the platform. >=20 > + >=20 > +**/ >=20 > +VOID >=20 > +CollectProcessorLocationData( >=20 > + IN COLLECT_CPUID_CACHE_DATA_CONTEXT *Context, >=20 > + IN UINTN NumberOfProcessor >=20 > + ) >=20 > +{ >=20 > + UINTN ProcessorNum; >=20 > + UINTN CacheParamLeafNum; >=20 > + EFI_PROCESSOR_INFORMATION ProcessorInfo; >=20 > + IN CPUID_CACHE_DATA *CpuidCacheData; >=20 > + >=20 > + for (ProcessorNum =3D 0; ProcessorNum < NumberOfProcessor; > ProcessorNum++) { >=20 > + CpuidCacheData =3D &Context- > >CpuidCacheData[MAX_NUM_OF_CACHE_PARAMS_LEAF * ProcessorNum]; >=20 > + ProcessorInfo =3D GetCurrentProcessorInfo(Context->MpServices, > ProcessorNum); >=20 > + >=20 > + for (CacheParamLeafNum =3D 0; CacheParamLeafNum < > MAX_NUM_OF_CACHE_PARAMS_LEAF; CacheParamLeafNum++) { >=20 > + CpuidCacheData[CacheParamLeafNum].Location.Package =3D > ProcessorInfo.Location.Package; >=20 > + CpuidCacheData[CacheParamLeafNum].Location.Core =3D > ProcessorInfo.Location.Core; >=20 > + CpuidCacheData[CacheParamLeafNum].Location.Thread =3D > ProcessorInfo.Location.Thread; >=20 > + CpuidCacheData[CacheParamLeafNum].ApicId =3D > (UINT32)ProcessorInfo.ProcessorId; >=20 > + } >=20 > + } >=20 > +} >=20 > + >=20 > +/** >=20 > + Collect CpuCacheInfo data from the CpuidCacheData. >=20 > + >=20 > + @param[in] CpuidCacheData Pointer to the CpuidCacheData arra= y. >=20 > + @param[in] CpuidCacheDataCount The length of CpuidCacheData array= . >=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_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 > +CollectCpuCacheInfoData ( >=20 > + IN CPUID_CACHE_DATA *CpuidCacheData, >=20 > + IN UINTN CpuidCacheDataCount, >=20 > + IN OUT CPU_CACHE_INFO *CpuCacheInfo, >=20 > + IN OUT UINTN *CpuCacheInfoCount >=20 > + ) >=20 > +{ >=20 > + EFI_STATUS Status; >=20 > + UINT32 NumberOfPackage; >=20 > + UINT8 NumberOfCoreType; >=20 > + UINTN TotalNumberOfCoreType; >=20 > + CPU_CACHE_INFO *TempCpuCacheInfo; >=20 > + UINTN TempCacheInfoIndex; >=20 > + UINTN TempCpuCacheInfoCount; >=20 > + UINTN PackageNum; >=20 > + UINTN CurrentCacheDataIndex; >=20 > + UINTN NextCacheDataIndex; >=20 > + UINTN CacheInfoIndex; >=20 > + UINTN Count; >=20 > + >=20 > + // >=20 > + // Get number of Packages. >=20 > + // >=20 > + NumberOfPackage =3D GetNumberOfPackage (CpuidCacheData, > CpuidCacheDataCount); >=20 > + DEBUG((DEBUG_ERROR, "[CacheInfoLib] NumberOfPackage =3D %d\n", > NumberOfPackage)); >=20 > + >=20 > + // >=20 > + // Get number of core types for each package and count the total numbe= r. >=20 > + // E.g. If Packege1 and Package2 both have 2 core types, the total num= ber > is 4. >=20 > + // >=20 > + TotalNumberOfCoreType =3D 0; >=20 > + >=20 > + for (PackageNum =3D 0; PackageNum < NumberOfPackage; PackageNum++) { >=20 > + NumberOfCoreType =3D > GetNumberOfCoreTypePerPackage(CpuidCacheData, CpuidCacheDataCount, > PackageNum); >=20 > + DEBUG((DEBUG_ERROR, "[CacheInfoLib] Package%d: NumberOfCoreType > =3D %d\n", PackageNum, NumberOfCoreType)); >=20 > + >=20 > + TotalNumberOfCoreType +=3D NumberOfCoreType; >=20 > + } >=20 > + DEBUG((DEBUG_ERROR, "[CacheInfoLib] TotalNumberOfCoreType =3D %d\n", > TotalNumberOfCoreType)); >=20 > + >=20 > + TempCpuCacheInfoCount =3D TotalNumberOfCoreType * > MAX_NUM_OF_CACHE_PARAMS_LEAF; >=20 > + TempCpuCacheInfo =3D AllocatePages > (EFI_SIZE_TO_PAGES(TempCpuCacheInfoCount * > sizeof(*TempCpuCacheInfo))); >=20 > + ASSERT(TempCpuCacheInfo !=3D NULL); >=20 > + if (TempCpuCacheInfo =3D=3D NULL) { >=20 > + return EFI_OUT_OF_RESOURCES; >=20 > + } >=20 > + >=20 > + ZeroMem(TempCpuCacheInfo, > EFI_PAGES_TO_SIZE(EFI_SIZE_TO_PAGES(TempCpuCacheInfoCount * > sizeof(*TempCpuCacheInfo)))); >=20 > + >=20 > + // >=20 > + // TempCpuCacheInfo is empty. >=20 > + // >=20 > + Count =3D 0; >=20 > + >=20 > + for (CurrentCacheDataIndex =3D 0; CurrentCacheDataIndex < > CpuidCacheDataCount; CurrentCacheDataIndex++) { >=20 > + if (CpuidCacheData[CurrentCacheDataIndex].CacheSizeinKB =3D=3D 0) >=20 > + continue; >=20 > + >=20 > + // >=20 > + // For the sharing caches, clear their CacheSize. >=20 > + // >=20 > + for (NextCacheDataIndex =3D CurrentCacheDataIndex + 1; > NextCacheDataIndex < CpuidCacheDataCount; NextCacheDataIndex++) { >=20 > + if (CpuidCacheData[NextCacheDataIndex].CacheSizeinKB =3D=3D 0) >=20 > + continue; >=20 > + >=20 > + if (CpuidCacheData[CurrentCacheDataIndex].Location.Package =3D=3D > CpuidCacheData[NextCacheDataIndex].Location.Package && \ >=20 > + CpuidCacheData[CurrentCacheDataIndex].CoreType =3D=3D > CpuidCacheData[NextCacheDataIndex].CoreType && \ >=20 > + CpuidCacheData[CurrentCacheDataIndex].CacheLevel =3D=3D > CpuidCacheData[NextCacheDataIndex].CacheLevel && \ >=20 > + CpuidCacheData[CurrentCacheDataIndex].CacheType =3D=3D > CpuidCacheData[NextCacheDataIndex].CacheType && \ >=20 > + (CpuidCacheData[CurrentCacheDataIndex].ApicId & > ~CpuidCacheData[CurrentCacheDataIndex].CacheShareBits) =3D=3D \ >=20 > + (CpuidCacheData[NextCacheDataIndex].ApicId & > ~CpuidCacheData[NextCacheDataIndex].CacheShareBits)) { >=20 > + CpuidCacheData[NextCacheDataIndex].CacheSizeinKB =3D 0; // uses = the > sharing cache >=20 > + } >=20 > + } >=20 > + >=20 > + // >=20 > + // For the cache has already existed in TempCpuCacheInfo buffer, > increase its CacheCount. >=20 > + // >=20 > + for (TempCacheInfoIndex =3D 0; TempCacheInfoIndex < > TempCpuCacheInfoCount; TempCacheInfoIndex++) { >=20 > + if (CpuidCacheData[CurrentCacheDataIndex].Location.Package =3D=3D > TempCpuCacheInfo[TempCacheInfoIndex].Package && \ >=20 > + CpuidCacheData[CurrentCacheDataIndex].CoreType =3D=3D > TempCpuCacheInfo[TempCacheInfoIndex].CoreType && \ >=20 > + CpuidCacheData[CurrentCacheDataIndex].CacheLevel =3D=3D > TempCpuCacheInfo[TempCacheInfoIndex].CacheLevel && \ >=20 > + CpuidCacheData[CurrentCacheDataIndex].CacheType =3D=3D > TempCpuCacheInfo[TempCacheInfoIndex].CacheType) { >=20 > + TempCpuCacheInfo[TempCacheInfoIndex].CacheCount++; >=20 > + break; >=20 > + } >=20 > + } >=20 > + >=20 > + // >=20 > + // For the new cache with different Package, CoreType, CacheLevel or > CacheType, copy its >=20 > + // data into TempCpuCacheInfo buffer. >=20 > + // >=20 > + if (TempCacheInfoIndex =3D=3D TempCpuCacheInfoCount) { >=20 > + TempCpuCacheInfo[Count].Package =3D > CpuidCacheData[CurrentCacheDataIndex].Location.Package; >=20 > + TempCpuCacheInfo[Count].CoreType =3D > CpuidCacheData[CurrentCacheDataIndex].CoreType; >=20 > + TempCpuCacheInfo[Count].CacheLevel =3D > CpuidCacheData[CurrentCacheDataIndex].CacheLevel; >=20 > + TempCpuCacheInfo[Count].CacheType =3D > CpuidCacheData[CurrentCacheDataIndex].CacheType; >=20 > + TempCpuCacheInfo[Count].CacheSizeinKB =3D > CpuidCacheData[CurrentCacheDataIndex].CacheSizeinKB; >=20 > + TempCpuCacheInfo[Count].CacheCount =3D 1; >=20 > + >=20 > + Count++; >=20 > + ASSERT(Count <=3D TempCpuCacheInfoCount); >=20 > + } >=20 > + } >=20 > + >=20 > + PrintCpuidCacheDataTable(CpuidCacheData, CpuidCacheDataCount); >=20 > + >=20 > + if (*CpuCacheInfoCount < Count) { >=20 > + Status =3D EFI_BUFFER_TOO_SMALL; >=20 > + } else { >=20 > + Status =3D EFI_SUCCESS; >=20 > + >=20 > + for (CacheInfoIndex =3D 0; CacheInfoIndex < Count; CacheInfoIndex++)= { >=20 > + CopyMem(&CpuCacheInfo[CacheInfoIndex], > &TempCpuCacheInfo[CacheInfoIndex], sizeof(*CpuCacheInfo)); >=20 > + } >=20 > + >=20 > + PrintCpuCacheInfoTable(CpuCacheInfo, Count); >=20 > + } >=20 > + >=20 > + *CpuCacheInfoCount =3D Count; >=20 > + >=20 > + FreePages(TempCpuCacheInfo, > EFI_SIZE_TO_PAGES(TempCpuCacheInfoCount * > sizeof(*TempCpuCacheInfo))); >=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_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 NumberOfProcessor; >=20 > + UINTN CpuidCacheDataCount; >=20 > + COLLECT_CPUID_CACHE_DATA_CONTEXT Context; >=20 > + >=20 > + if (CpuCacheInfoCount =3D=3D NULL) { >=20 > + return EFI_INVALID_PARAMETER; >=20 > + >=20 > + } else if (*CpuCacheInfoCount !=3D 0 && CpuCacheInfo =3D=3D NULL) { >=20 > + return EFI_INVALID_PARAMETER; >=20 > + } >=20 > + >=20 > + // >=20 > + // Initialize COLLECT_CPUID_CACHE_DATA_CONTEXT.MpServices. >=20 > + // >=20 > + Context.MpServices =3D GetMpServices(); >=20 > + >=20 > + NumberOfProcessor =3D GetNumberOfProcessor (Context.MpServices); >=20 > + DEBUG((DEBUG_ERROR, "[CacheInfoLib] NumberOfProcessor =3D 0x%x\n", > NumberOfProcessor)); >=20 > + >=20 > + // >=20 > + // Initialize COLLECT_CPUID_CACHE_DATA_CONTEXT.CpuidCacheData. >=20 > + // >=20 > + CpuidCacheDataCount =3D NumberOfProcessor * > MAX_NUM_OF_CACHE_PARAMS_LEAF; >=20 > + Context.CpuidCacheData =3D > AllocatePages(EFI_SIZE_TO_PAGES(CpuidCacheDataCount * > sizeof(*Context.CpuidCacheData))); >=20 > + ASSERT(Context.CpuidCacheData !=3D NULL); >=20 > + if (Context.CpuidCacheData =3D=3D NULL) { >=20 > + return EFI_OUT_OF_RESOURCES; >=20 > + } >=20 > + >=20 > + ZeroMem(Context.CpuidCacheData, > EFI_PAGES_TO_SIZE(EFI_SIZE_TO_PAGES(CpuidCacheDataCount * > sizeof(*Context.CpuidCacheData)))); >=20 > + >=20 > + // >=20 > + // Wakeup all processors for CpuidCacheData(core and cache data) > collection. >=20 > + // >=20 > + CollectCoreAndCacheDataForAll (&Context); >=20 > + >=20 > + // >=20 > + // Collect CpuidCacheData(ProcessorLocation data) of all processors. >=20 > + // >=20 > + CollectProcessorLocationData (&Context, NumberOfProcessor); >=20 > + >=20 > + // >=20 > + // Collect CpuCacheInfo data from CpuidCacheData. >=20 > + // >=20 > + Status =3D CollectCpuCacheInfoData (Context.CpuidCacheData, > CpuidCacheDataCount, CpuCacheInfo, CpuCacheInfoCount); >=20 > + DEBUG((DEBUG_ERROR, "[CacheInfoLib] CollectCpuCacheInfoData: %r > (CacheInfoCount =3D %d)\n", Status, *CpuCacheInfoCount)); >=20 > + >=20 > + FreePages(Context.CpuidCacheData, > EFI_SIZE_TO_PAGES(CpuidCacheDataCount * > sizeof(*Context.CpuidCacheData))); >=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..4c85150e7750 > --- /dev/null > +++ b/UefiCpuPkg/Library/CpuCacheInfoLib/DxeCpuCacheInfoLib.c > @@ -0,0 +1,131 @@ > +/** @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 > + 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 > +CollectCoreAndCacheData ( >=20 > + IN OUT VOID *Buffer >=20 > + ); >=20 > + >=20 > +/** >=20 > + Get EFI_MP_SERVICES_PROTOCOL pointer. >=20 > + >=20 > + @retval Return MP_SERVICES structure. >=20 > +**/ >=20 > +MP_SERVICES >=20 > +GetMpServices ( >=20 > + VOID >=20 > + ) >=20 > +{ >=20 > + EFI_STATUS Status; >=20 > + MP_SERVICES MpServices; >=20 > + >=20 > + Status =3D gBS->LocateProtocol (&gEfiMpServiceProtocolGuid, NULL, (VOI= D > **)&MpServices.Protocol); >=20 > + ASSERT_EFI_ERROR (Status); >=20 > + >=20 > + return MpServices; >=20 > +} >=20 > + >=20 > +/** >=20 > + Collect core and cache information of all APs and BSP via CPUID > instructions. >=20 > + >=20 > + @param[in] Context The pointer to > COLLECT_CPUID_CACHE_DATA_CONTEXT structure. >=20 > +**/ >=20 > +VOID >=20 > +CollectCoreAndCacheDataForAll ( >=20 > + IN COLLECT_CPUID_CACHE_DATA_CONTEXT *Context >=20 > + ) >=20 > +{ >=20 > + EFI_STATUS Status; >=20 > + MP_SERVICES MpServices; >=20 > + >=20 > + MpServices =3D Context->MpServices; >=20 > + >=20 > + Status =3D MpServices.Protocol->StartupAllAPs (MpServices.Protocol, > CollectCoreAndCacheData, TRUE, NULL, 0, Context, NULL); >=20 > + ASSERT_EFI_ERROR(Status); >=20 > + >=20 > + CollectCoreAndCacheData(Context); >=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 > + >=20 > + @retval Return EFI_PROCESSOR_INFORMATION structure of requested > logical processors. >=20 > +**/ >=20 > +EFI_PROCESSOR_INFORMATION >=20 > +GetCurrentProcessorInfo ( >=20 > + IN MP_SERVICES MpServices, >=20 > + IN UINTN ProcessorNum >=20 > + >=20 > + ) >=20 > +{ >=20 > + EFI_STATUS Status; >=20 > + EFI_PROCESSOR_INFORMATION ProcessorInfo; >=20 > + >=20 > + Status =3D MpServices.Protocol->GetProcessorInfo (MpServices.Protocol, > ProcessorNum, &ProcessorInfo); >=20 > + ASSERT_EFI_ERROR(Status); >=20 > + >=20 > + return 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 > +GetCurrentProcessorNum ( >=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 > +GetNumberOfProcessor ( >=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..2d40b7086dc7 > --- /dev/null > +++ b/UefiCpuPkg/Library/CpuCacheInfoLib/PeiCpuCacheInfoLib.c > @@ -0,0 +1,130 @@ > +/** @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 > + 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 > +CollectCoreAndCacheData ( >=20 > + IN OUT VOID *Buffer >=20 > + ); >=20 > + >=20 > +/** >=20 > + Get EDKII_PEI_MP_SERVICES2_PPI pointer. >=20 > + >=20 > + @retval Return MP_SERVICES structure. >=20 > +**/ >=20 > +MP_SERVICES >=20 > +GetMpServices ( >=20 > + VOID >=20 > + ) >=20 > +{ >=20 > + EFI_STATUS Status; >=20 > + MP_SERVICES MpServices; >=20 > + >=20 > + Status =3D PeiServicesLocatePpi (&gEdkiiPeiMpServices2PpiGuid, 0, NULL= , > (VOID **)&MpServices.Ppi); >=20 > + ASSERT_EFI_ERROR (Status); >=20 > + >=20 > + return MpServices; >=20 > +} >=20 > + >=20 > +/** >=20 > + Collect core and cache information of all APs and BSP via CPUID > instructions. >=20 > + >=20 > + @param[in] Context The pointer to > COLLECT_CPUID_CACHE_DATA_CONTEXT structure. >=20 > +**/ >=20 > +VOID >=20 > +CollectCoreAndCacheDataForAll ( >=20 > + IN COLLECT_CPUID_CACHE_DATA_CONTEXT *Context >=20 > + ) >=20 > +{ >=20 > + EFI_STATUS Status; >=20 > + MP_SERVICES MpServices; >=20 > + >=20 > + MpServices =3D Context->MpServices; >=20 > + >=20 > + Status =3D MpServices.Ppi->StartupAllCPUs (MpServices.Ppi, > CollectCoreAndCacheData, 0, Context); >=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 > + >=20 > + @retval Return EFI_PROCESSOR_INFORMATION structure of requested > logical processors. >=20 > +**/ >=20 > +EFI_PROCESSOR_INFORMATION >=20 > +GetCurrentProcessorInfo ( >=20 > + IN MP_SERVICES MpServices, >=20 > + IN UINTN ProcessorNum >=20 > + >=20 > + ) >=20 > +{ >=20 > + EFI_STATUS Status; >=20 > + EFI_PROCESSOR_INFORMATION ProcessorInfo; >=20 > + >=20 > + Status =3D MpServices.Ppi->GetProcessorInfo (MpServices.Ppi, Processor= Num, > &ProcessorInfo); >=20 > + ASSERT_EFI_ERROR(Status); >=20 > + >=20 > + return 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 > +GetCurrentProcessorNum ( >=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 > +GetNumberOfProcessor ( >=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..475764f893d0 > --- /dev/null > +++ b/UefiCpuPkg/Include/Library/CpuCacheInfoLib.h > @@ -0,0 +1,68 @@ > +/** @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(1A).Eax[31:24].Coretype >=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(04).Eax[07:05].CacheLevel >=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(04).Eax[04:00].CacheTypeField >=20 > + // >=20 > + UINT8 CacheType : 5; >=20 > + // >=20 > + // Size of single cache that this package's this type of logical proce= ssor > corresponds to. >=20 > + // Value =3D (CPUID(04).Ebx[31:22].Ways + 1) * > (CPUID(04).Ebx[21:12].Partitions + 1) * / >=20 > + // (CPUID(04).Ebx[11:00].LineSize + 1) * (CPUID(04).Ecx[31:00]= .Sets + 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_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..f509861a5f4c > --- /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_CORE DXE_DRIVER > DXE_RUNTIME_DRIVER UEFI_APPLICATION UEFI_DRIVER >=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 > + gEfiMpServiceProtocolGuid >=20 > diff --git a/UefiCpuPkg/Library/CpuCacheInfoLib/InternalCpuCacheInfoLib.h > b/UefiCpuPkg/Library/CpuCacheInfoLib/InternalCpuCacheInfoLib.h > new file mode 100644 > index 000000000000..934d5f2fa5a1 > --- /dev/null > +++ b/UefiCpuPkg/Library/CpuCacheInfoLib/InternalCpuCacheInfoLib.h > @@ -0,0 +1,64 @@ > +/** @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 > + >=20 > +typedef struct { >=20 > + // >=20 > + // APIC ID. >=20 > + // >=20 > + UINT32 ApicId; >=20 > + // >=20 > + // Processor location information. >=20 > + // The information comes from MP Services. >=20 > + // >=20 > + EFI_CPU_PHYSICAL_LOCATION Location; >=20 > + // >=20 > + // Core type of logical processor. >=20 > + // Value =3D CPUID(1A).Eax[31:24].Coretype >=20 > + // >=20 > + UINT8 CoreType; >=20 > + // >=20 > + // Level of the cache. >=20 > + // Value =3D CPUID(04).Eax[07:05].CacheLevel >=20 > + // >=20 > + UINT8 CacheLevel : 3; >=20 > + // >=20 > + // Type of the cache. >=20 > + // Value =3D CPUID(04).Eax[04:00].CacheTypeField >=20 > + // >=20 > + UINT8 CacheType : 5; >=20 > + // >=20 > + // Cache share bits. >=20 > + // Value =3D > CPUID(04).Eax[25:14].MaximumAddressableIdsForLogicalProcessors >=20 > + // >=20 > + UINT16 CacheShareBits; >=20 > + // >=20 > + // Size of single cache. >=20 > + // Value =3D (CPUID(04).Ebx[31:22].Ways + 1) * > (CPUID(04).Ebx[21:12].Partitions + 1) * / >=20 > + // (CPUID(04).Ebx[11:00].LineSize + 1) * (CPUID(04).Ecx[31:00]= .Sets + 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_CACHE_DATA *CpuidCacheData; >=20 > +} COLLECT_CPUID_CACHE_DATA_CONTEXT; >=20 > + >=20 > +#endif >=20 > diff --git a/UefiCpuPkg/Library/CpuCacheInfoLib/PeiCpuCacheInfoLib.inf > b/UefiCpuPkg/Library/CpuCacheInfoLib/PeiCpuCacheInfoLib.inf > new file mode 100644 > index 000000000000..a84b50219e53 > --- /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|PEI_CORE 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 > + gEdkiiPeiMpServices2PpiGuid >=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 > terCpuFeaturesLib.inf >=20 > + > CpuCacheInfoLib|UefiCpuPkg/Library/CpuCacheInfoLib/PeiCpuCacheInfoLib.i > nf >=20 >=20 >=20 > [LibraryClasses.IA32.PEIM, LibraryClasses.X64.PEIM] >=20 >=20 > PeiServicesTablePointerLib|MdePkg/Library/PeiServicesTablePointerLibIdt/P= e > iServicesTablePointerLibIdt.inf >=20 > @@ -86,6 +87,7 @@ [LibraryClasses.common.DXE_DRIVER] >=20 > CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeC > puExceptionHandlerLib.inf >=20 > MpInitLib|UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf >=20 >=20 > RegisterCpuFeaturesLib|UefiCpuPkg/Library/RegisterCpuFeaturesLib/DxeRegi > sterCpuFeaturesLib.inf >=20 > + > CpuCacheInfoLib|UefiCpuPkg/Library/CpuCacheInfoLib/DxeCpuCacheInfoLib.i > nf >=20 >=20 >=20 > [LibraryClasses.common.DXE_SMM_DRIVER] >=20 >=20 > SmmServicesTableLib|MdePkg/Library/SmmServicesTableLib/SmmServicesTa > bleLib.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