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.2564.1617848402460816500 for ; Wed, 07 Apr 2021 19:20:03 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@intel.onmicrosoft.com header.s=selector2-intel-onmicrosoft-com header.b=qq/pFI5C; spf=pass (domain: intel.com, ip: 134.134.136.24, mailfrom: eric.dong@intel.com) IronPort-SDR: 4mV9lrTOMSVJIzkSZTTVogY40WeLIAxT6h6hzV9BO4B3e2Rg+9O34rscN6xdGrXOeOedw6YN+V WAnbouCErGow== X-IronPort-AV: E=McAfee;i="6000,8403,9947"; a="193555310" X-IronPort-AV: E=Sophos;i="5.82,205,1613462400"; d="scan'208";a="193555310" Received: from orsmga007.jf.intel.com ([10.7.209.58]) by orsmga102.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 07 Apr 2021 19:20:01 -0700 IronPort-SDR: 79KOXeorNn76FW9oNRqiI/37iGPSmaapkeKK89NzjPEZjDiLOUcEieozF+6tYVDOLKlkrbGTkE 2+2gzrVqHzMQ== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.82,205,1613462400"; d="scan'208";a="418978091" Received: from orsmsx605.amr.corp.intel.com ([10.22.229.18]) by orsmga007.jf.intel.com with ESMTP; 07 Apr 2021 19:20:01 -0700 Received: from orsmsx607.amr.corp.intel.com (10.22.229.20) 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.2106.2; Wed, 7 Apr 2021 19:20:01 -0700 Received: from orsmsx602.amr.corp.intel.com (10.22.229.15) by ORSMSX607.amr.corp.intel.com (10.22.229.20) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2106.2; Wed, 7 Apr 2021 19:20:00 -0700 Received: from orsedg603.ED.cps.intel.com (10.7.248.4) by orsmsx602.amr.corp.intel.com (10.22.229.15) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2106.2 via Frontend Transport; Wed, 7 Apr 2021 19:20:00 -0700 Received: from NAM10-BN7-obe.outbound.protection.outlook.com (104.47.70.106) by edgegateway.intel.com (134.134.137.100) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.1.2106.2; Wed, 7 Apr 2021 19:20:00 -0700 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=H3Fc6VhSHbpaUsLq/A/9C0EIk9ouxlPn3sgA/zOlcfLYgeYczBxknPBq4in95mkWIf51m28aGm1lz/og66UY885+VR5FaEzXFr8MdnXJS82OIGezj77MojRtQSez+UyD7sNzLQ7j6FGCfM4/64oNCM2ZbHmR9PHeGz2ZL2TpDIK87ZcNcLCamiYL82GN/Z03Qkrl86YTTTPEkCEKXankisszbgoOChD8N/AmokFE4wQGUv7Lx0/pMKS8yOPnc9sps/OfNzftKSb9ILS4DmnOoEBOYv5C8NTrsvq5PsWwwQfU59CI7Ip+QUdREEcZFbxtoA0eCvcfba5Y7GezPCdgwQ== 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=YV6KoStMlNe7cWOghBIztkShkayBlXlO1iDRl/adh+U=; b=AoGEumQQukBuLXMrTN+JNPNPm/kimBsi3dA510qdNu+GBnU0RWSGUya4qhNCZY+9frV25TQxCDPF9Q9JrhR3nJxYCN0hAXYlJ7qgRUYlVVM10zFfq+KyhtvUeTr38bnG+XTN4jyGKkRdujBGE5EJrMlRd2oU/AfeiZRN0omIh38SyQdRDljFcJq3D27cgguyCQewlO5Lz+nhLU2z9bQ5evaykuh+vEtNLhJQJW0IGQZcamJCKGyjfiiS4PrQD0n66gLIAiZiR+UZLVyPtYkaN5p92Vh8zM5UJMJtUM5P+X92Y7UireqzfnEw1DEVkMdnxtDHMk+IdgDhL2hVNLcXKg== 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=YV6KoStMlNe7cWOghBIztkShkayBlXlO1iDRl/adh+U=; b=qq/pFI5CJI0uwIPKCfqgSiv80HdvMTWTF7OrJBNP498HAwpEvsOV8Iymeraj7YuZjYMlmW6SVN9bW3Xk2Fttrxt31ivOGTZIUMNEsTGbSXZaKywypVuTbH1aYKG0XJSig2PYvpUJwQ8Cdr3wrz5QogF68Mw9FjtCsRLhpz03IuA= Received: from CY4PR11MB1272.namprd11.prod.outlook.com (2603:10b6:903:29::9) by CY4PR11MB1317.namprd11.prod.outlook.com (2603:10b6:903:2f::8) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3999.29; Thu, 8 Apr 2021 02:19:58 +0000 Received: from CY4PR11MB1272.namprd11.prod.outlook.com ([fe80::918c:7df3:f688:d5e9]) by CY4PR11MB1272.namprd11.prod.outlook.com ([fe80::918c:7df3:f688:d5e9%5]) with mapi id 15.20.3999.032; Thu, 8 Apr 2021 02:19:58 +0000 From: "Dong, Eric" To: "Ni, Ray" , "devel@edk2.groups.io" CC: Laszlo Ersek , "Kumar, Rahul1" Subject: Re: [PATCH 1/4] UefiCpuPkg: Add MicrocodeLib for loading microcode Thread-Topic: [PATCH 1/4] UefiCpuPkg: Add MicrocodeLib for loading microcode Thread-Index: AQHXJ4UyjJVDBG8IJEqhRL4tqDuvEqqp7CsQ Date: Thu, 8 Apr 2021 02:19:58 +0000 Message-ID: References: <20210402055807.858-1-ray.ni@intel.com> <20210402055807.858-2-ray.ni@intel.com> In-Reply-To: <20210402055807.858-2-ray.ni@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.102.204.51] x-ms-publictraffictype: Email x-ms-office365-filtering-correlation-id: b4f35ed5-7f0c-4124-7168-08d8fa34cece x-ms-traffictypediagnostic: CY4PR11MB1317: x-ms-exchange-transport-forked: True x-microsoft-antispam-prvs: x-ms-oob-tlc-oobclassifiers: OLM:8882; x-ms-exchange-senderadcheck: 1 x-microsoft-antispam: BCL:0; x-microsoft-antispam-message-info: TS3TasVmYOgaf3B6Wx01w9UWNFkkBGD4bvFhaJge9sXLaGR7RshaJBEeNM09pmS6Ou667r6kosvyOuObC/WdaN1wd+8vORdDbK0bOAJDZF0xQ45CAgNVT37D2aywMk7mua5LeZPYM50w+PiGehldUIbF8d1f0clmPztmEmdcDibMrr0oc9fjRzjSsHu/foeTlk/Q4VoR/h22mEItDIcNnnHWf6pvHc/fXkZ4nL97zwMif20YpMb32mJvT2244KJg47bFflVQAglxx7KhQ8qeWnQAA71Bh4SsHyU+1vsYtD51ZeHMt9yNVhLAjwWM9CSJ+xjy0oMTP2Iuvisv+B7LMZ9afBOLAnWF9vvPeYg2V/BTnIpaKSISi+iCLzY/lMKZpoJr4DseZbcEWVD4qxpfTZrS32DSHKySyt7fEw4ASxBp01ynuVz05FlJLThqhwcVwueBEsfQK8CWK4G74SFIHBwjFQPj9L3NlebQczFywf22Tz8ygewzghb8d9+2rUBpXXwFGoo9E3xyHtzS+YB/ZNFnF4t5dag3We16xpO3frhU1+hBgo31JPxzGUnXozTlL9+6LJyDUey/pPX9YLm4tz3ZO2lRY8PbWEXgsyTYUPKyE3cHmMzI1sA+2dzOF4J/MWcD11zODXfN5Bpr8h2Wn1yckU4FIx9ucrOrN/RpHvY= x-forefront-antispam-report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:CY4PR11MB1272.namprd11.prod.outlook.com;PTR:;CAT:NONE;SFS:(366004)(346002)(376002)(136003)(39860400002)(396003)(478600001)(38100700001)(6506007)(53546011)(5660300002)(110136005)(8936002)(83380400001)(54906003)(7696005)(19627235002)(8676002)(186003)(316002)(30864003)(66946007)(66446008)(9686003)(64756008)(86362001)(26005)(66476007)(66556008)(76116006)(71200400001)(2906002)(52536014)(4326008)(107886003)(33656002)(55016002)(579004);DIR:OUT;SFP:1102; x-ms-exchange-antispam-messagedata: =?us-ascii?Q?8TG9jAur6CgtWyqnG+LeNEtls+mq0bZoieAqt9MghjxTD9s6V0TlkmDV5AaY?= =?us-ascii?Q?QygeUeccM5bQVcBUjdPJWF4GUGQlQQMgNsS5GwIn2n139/mlBOo5DKE3l2hP?= =?us-ascii?Q?DKmsQHZxytDahoYGh+txr+s8aB8/d3VJrSKs4oPTqHzBHKROaoI50fcskTRX?= =?us-ascii?Q?y26SqWLPar0gXaavNVhsNzL7OditGPH60iG3OTw97+RbyowmrVgnXw+DD8WI?= =?us-ascii?Q?FerZSca43EnrHugEeO+xTUK6KLhwmr0JPa5INbcLSfRxGJz83pw1SHsLT518?= =?us-ascii?Q?8oyvfNsj9cGDVAHz4YRaSc7xiSkItPw2i7XleWNKgIE1CW+fdlafuDuKN7ZA?= =?us-ascii?Q?f7FYf85qgmGPTAViCDEuvZnYQlwxtfXXfVC/a3zH8FvOQ0QiFepFxsw5HtXp?= =?us-ascii?Q?GMmzNqXGm3Ue9KkVkBDEDhDoqFhh3ErkiHxap+DUEHPzLbVMkoMcKkKDL09T?= =?us-ascii?Q?d4Xge0KJWNNip1LHn0NpD1889AJxaICGp/BpTYqby6CUbnUZNTvggwQUOUAX?= =?us-ascii?Q?fzsuJ5cYn+YLjRLiHUIMFquuIwERoa9PvBPs9oWWOX+mQgDxpfCwF111X2ik?= =?us-ascii?Q?EpUzw1dTe59VIeGfx68W7MPb7pag+CR2+s6zHKWNptVWp1/1pvNxStbvqnvx?= =?us-ascii?Q?cRaKM5+Lg9185kbtcgww3vLJivtpYlMGEc/vxc3ea2x4bipjsnrt8++CAYwv?= =?us-ascii?Q?orBsP5GbnZeB+phOlLE2IYHH/kxQXzkg/fFGrBXNVKltS8TXFPvOOEyDxvtN?= =?us-ascii?Q?aRUib0/GpRc0z/dMtZcCqBWR8JtlOUNjuI60r1RQomm/VcBmhkWkSBJZF6G4?= =?us-ascii?Q?0XrsuYAcvJlQjQMX1GprZNNtejijXIXH8UmlgUcyYqqHYSenwwLSfE4i5UlG?= =?us-ascii?Q?1rANFoRc/+B5Ahht8tmb1a7Wb8/IA0+5DKuIUOQnMPplpwhQ2iCHdSVMvbtj?= =?us-ascii?Q?2RkpE2OA6A+RJRVnz0PTo2pI3D58e43tZr/JCpnHwhzxOSIbt28usONN8/I7?= =?us-ascii?Q?U7UxIplsZ3GSXSGAN+MQ82LFV9Yv7LY5FKNVaL6HZq5RLFEAlv/DRP3YFvFs?= =?us-ascii?Q?6y4MY/aPlCMIyRM61aqIg8j0lQchMsPVKz35X+5jNU/n0aXPPVFfCHI+v1eG?= =?us-ascii?Q?sCns8DzNFt1GBL2VYSuk9IMr3qppGGtp2L/RWaND7qMKCs5Kg04gD3dkGetM?= =?us-ascii?Q?chRq5dLjWSzzq6o2e6OFf9uPmtZC4tzB1mJRqs4PM4F9CpZR7urG+2Aclyv6?= =?us-ascii?Q?qi7LZeroz0AZuUs41I8lMyBP3a4QlSoVkKzSqd8PMKiUo50+5PG71NQ1pRVt?= =?us-ascii?Q?KhuuUMKteKwx1OCiuEmFBr5w?= MIME-Version: 1.0 X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-AuthSource: CY4PR11MB1272.namprd11.prod.outlook.com X-MS-Exchange-CrossTenant-Network-Message-Id: b4f35ed5-7f0c-4124-7168-08d8fa34cece X-MS-Exchange-CrossTenant-originalarrivaltime: 08 Apr 2021 02:19:58.6804 (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: 6IAvm5IPjqF6BLqmsIdiYk6gZwUnx1jKtlR9iFBteZwRrtX8+54f7QYfMZrzQBUZ6JKQELlA6M6OelN50fpv5Q== X-MS-Exchange-Transport-CrossTenantHeadersStamped: CY4PR11MB1317 Return-Path: eric.dong@intel.com X-OriginatorOrg: intel.com Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Reviewed-by: Eric Dong -----Original Message----- From: Ni, Ray =20 Sent: Friday, April 2, 2021 1:58 PM To: devel@edk2.groups.io Cc: Dong, Eric ; Laszlo Ersek ; Kum= ar, Rahul1 Subject: [PATCH 1/4] UefiCpuPkg: Add MicrocodeLib for loading microcode Signed-off-by: Ray Ni Cc: Eric Dong Cc: Laszlo Ersek Cc: Rahul Kumar --- UefiCpuPkg/Include/Library/MicrocodeLib.h | 120 +++++++ .../Library/MicrocodeLib/MicrocodeLib.c | 322 ++++++++++++++++++ .../Library/MicrocodeLib/MicrocodeLib.inf | 32 ++ UefiCpuPkg/UefiCpuPkg.dec | 5 +- UefiCpuPkg/UefiCpuPkg.dsc | 1 + 5 files changed, 479 insertions(+), 1 deletion(-) create mode 100644 UefiCpuPkg/Include/Library/MicrocodeLib.h create mode 100644 UefiCpuPkg/Library/MicrocodeLib/MicrocodeLib.c create mode 100644 UefiCpuPkg/Library/MicrocodeLib/MicrocodeLib.inf diff --git a/UefiCpuPkg/Include/Library/MicrocodeLib.h b/UefiCpuPkg/Include= /Library/MicrocodeLib.h new file mode 100644 index 0000000000..2570c43cce --- /dev/null +++ b/UefiCpuPkg/Include/Library/MicrocodeLib.h @@ -0,0 +1,120 @@ +/** @file + Public include file for Microcode library. + + Copyright (c) 2021, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __MICROCODE_LIB_H__ +#define __MICROCODE_LIB_H__ + +#include +#include + +/** + Get microcode update signature of currently loaded microcode update. + + @return Microcode signature. +**/ +UINT32 +EFIAPI +GetProcessorMicrocodeSignature ( + VOID + ); + +/** + Get the processor signature and platform ID for current processor. + + @param MicrocodeCpuId Return the processor signature and platform ID. +**/ +VOID +EFIAPI +GetProcessorMicrocodeCpuId ( + EDKII_PEI_MICROCODE_CPU_ID *MicrocodeCpuId + ); + +/** + Return the total size of the microcode entry. + + Logic follows pseudo code in SDM as below: + + N =3D 512 + If (Update.DataSize !=3D 00000000H) + N =3D Update.TotalSize / 4 + + If Microcode is NULL, then ASSERT. + + @param Microcode Pointer to the microcode entry. + + @return The microcode total size. +**/ +UINT32 +EFIAPI +GetMicrocodeLength ( + IN CPU_MICROCODE_HEADER *Microcode + ); + +/** + Load the microcode to the processor. + + If Microcode is NULL, then ASSERT. + + @param Microcode Pointer to the microcode entry. +**/ +VOID +EFIAPI +LoadMicrocode ( + IN CPU_MICROCODE_HEADER *Microcode + ); + +/** + Detect whether specified processor can find matching microcode patch and= load it. + + Microcode format is as below: + +----------------------------------------+------------------------------= -------------------+ + | CPU_MICROCODE_HEADER | = | + +----------------------------------------+ = V + | Update Data | = CPU_MICROCODE_HEADER.Checksum + +----------------------------------------+-------+ = ^ + | CPU_MICROCODE_EXTENDED_TABLE_HEADER | | = | + +----------------------------------------+ V = | + | CPU_MICROCODE_EXTENDED_TABLE[0] | CPU_MICROCODE_EXTENDED_TABLE= _HEADER.Checksum | + | CPU_MICROCODE_EXTENDED_TABLE[1] | ^ = | + | ... | | = | + +----------------------------------------+-------+----------------------= -------------------+ + + There may by multiple CPU_MICROCODE_EXTENDED_TABLE in this format. + The count of CPU_MICROCODE_EXTENDED_TABLE is indicated by ExtendedSignat= ureCount + of CPU_MICROCODE_EXTENDED_TABLE_HEADER structure. + + If Microcode is NULL, then ASSERT. + + @param Microcode Pointer to a microcode entry. + @param MicrocodeLength The total length of the microcode entry. + @param MinimumRevision The microcode whose revision <=3D MinimumRev= ision is treated as invalid. + Caller can supply value get from GetProcesso= rMicrocodeSignature() to check + whether the microcode is newer than loaded o= ne. + Caller can supply 0 to treat any revision (e= xcept 0) microcode as valid. + @param MicrocodeCpuIds Pointer to an array of processor signature a= nd platform ID that represents + a set of processors. + Caller can supply zero-element array to skip= the processor signature and + platform ID check. + @param MicrocodeCpuIdCount The number of elements in MicrocodeCpuIds. + @param VerifyChecksum FALSE to skip all the checksum verifications= . + + @retval TRUE The microcode is valid. + @retval FALSE The microcode is invalid. +**/ +BOOLEAN +EFIAPI +IsValidMicrocode ( + IN CPU_MICROCODE_HEADER *Microcode, + IN UINTN MicrocodeLength, + IN UINT32 MinimumRevision, + IN EDKII_PEI_MICROCODE_CPU_ID *MicrocodeCpuIds, + IN UINTN MicrocodeCpuIdCount, + IN BOOLEAN VerifyChecksum + ); + +#endif \ No newline at end of file diff --git a/UefiCpuPkg/Library/MicrocodeLib/MicrocodeLib.c b/UefiCpuPkg/Li= brary/MicrocodeLib/MicrocodeLib.c new file mode 100644 index 0000000000..03a43fdae7 --- /dev/null +++ b/UefiCpuPkg/Library/MicrocodeLib/MicrocodeLib.c @@ -0,0 +1,322 @@ +/** @file + Implementation of MicrocodeLib. + + Copyright (c) 2021, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include +#include +#include +#include +#include + +/** + Get microcode update signature of currently loaded microcode update. + + @return Microcode signature. +**/ +UINT32 +EFIAPI +GetProcessorMicrocodeSignature ( + VOID + ) +{ + MSR_IA32_BIOS_SIGN_ID_REGISTER BiosSignIdMsr; + + AsmWriteMsr64 (MSR_IA32_BIOS_SIGN_ID, 0); + AsmCpuid (CPUID_VERSION_INFO, NULL, NULL, NULL, NULL); + BiosSignIdMsr.Uint64 =3D AsmReadMsr64 (MSR_IA32_BIOS_SIGN_ID); + return BiosSignIdMsr.Bits.MicrocodeUpdateSignature; +} + +/** + Get the processor signature and platform ID for current processor. + + @param MicrocodeCpuId Return the processor signature and platform ID. +**/ +VOID +EFIAPI +GetProcessorMicrocodeCpuId ( + EDKII_PEI_MICROCODE_CPU_ID *MicrocodeCpuId + ) +{ + MSR_IA32_PLATFORM_ID_REGISTER PlatformIdMsr; + + ASSERT (MicrocodeCpuId !=3D NULL); + + PlatformIdMsr.Uint64 =3D AsmReadMsr64 (MSR_IA32_PLATFORM_ID); + MicrocodeCpuId->PlatformId =3D (UINT8) PlatformIdMsr.Bits.PlatformId; + AsmCpuid (CPUID_VERSION_INFO, &MicrocodeCpuId->ProcessorSignature, NULL,= NULL, NULL); +} + +/** + Return the total size of the microcode entry. + + Logic follows pseudo code in SDM as below: + + N =3D 512 + If (Update.DataSize !=3D 00000000H) + N =3D Update.TotalSize / 4 + + If Microcode is NULL, then ASSERT. + + @param Microcode Pointer to the microcode entry. + + @return The microcode total size. +**/ +UINT32 +EFIAPI +GetMicrocodeLength ( + IN CPU_MICROCODE_HEADER *Microcode + ) +{ + UINT32 TotalSize; + + ASSERT (Microcode !=3D NULL); + + TotalSize =3D 2048; + if (Microcode->DataSize !=3D 0) { + TotalSize =3D Microcode->TotalSize; + } + return TotalSize; +} + +/** + Load the microcode to the processor. + + If Microcode is NULL, then ASSERT. + + @param Microcode Pointer to the microcode entry. +**/ +VOID +EFIAPI +LoadMicrocode ( + IN CPU_MICROCODE_HEADER *Microcode + ) +{ + ASSERT (Microcode !=3D NULL); + + AsmWriteMsr64 (MSR_IA32_BIOS_UPDT_TRIG, (UINT64) (UINTN) (Microcode + 1)= ); +} + +/** + Determine if a microcode patch matchs the specific processor signature a= nd flag. + + @param[in] ProcessorSignature The processor signature field value in= a + microcode patch. + @param[in] ProcessorFlags The processor flags field value in a + microcode patch. + @param[in] MicrocodeCpuId A pointer to an array of EDKII_PEI_MIC= ROCODE_CPU_ID + structures. + @param[in] MicrocodeCpuIdCount Number of elements in MicrocodeCpuId a= rray. + + @retval TRUE The specified microcode patch matches to one of the Mic= rocodeCpuId. + @retval FALSE The specified microcode patch doesn't match to any of t= he MicrocodeCpuId. +**/ +BOOLEAN +IsProcessorMatchedMicrocode ( + IN UINT32 ProcessorSignature, + IN UINT32 ProcessorFlags, + IN EDKII_PEI_MICROCODE_CPU_ID *MicrocodeCpuId, + IN UINTN MicrocodeCpuIdCount + ) +{ + UINTN Index; + + if (MicrocodeCpuIdCount =3D=3D 0) { + return TRUE; + } + + for (Index =3D 0; Index < MicrocodeCpuIdCount; Index++) { + if ((ProcessorSignature =3D=3D MicrocodeCpuId[Index].ProcessorSignatur= e) && + (ProcessorFlags & (1 << MicrocodeCpuId[Index].PlatformId)) !=3D 0)= { + return TRUE; + } + } + + return FALSE; +} + +/** + Detect whether specified processor can find matching microcode patch and= load it. + + Microcode format is as below: + +----------------------------------------+------------------------------= -------------------+ + | CPU_MICROCODE_HEADER | = | + +----------------------------------------+ = V + | Update Data | = CPU_MICROCODE_HEADER.Checksum + +----------------------------------------+-------+ = ^ + | CPU_MICROCODE_EXTENDED_TABLE_HEADER | | = | + +----------------------------------------+ V = | + | CPU_MICROCODE_EXTENDED_TABLE[0] | CPU_MICROCODE_EXTENDED_TABLE= _HEADER.Checksum | + | CPU_MICROCODE_EXTENDED_TABLE[1] | ^ = | + | ... | | = | + +----------------------------------------+-------+----------------------= -------------------+ + + There may by multiple CPU_MICROCODE_EXTENDED_TABLE in this format. + The count of CPU_MICROCODE_EXTENDED_TABLE is indicated by ExtendedSignat= ureCount + of CPU_MICROCODE_EXTENDED_TABLE_HEADER structure. + + If Microcode is NULL, then ASSERT. + + @param Microcode Pointer to a microcode entry. + @param MicrocodeLength The total length of the microcode entry. + @param MinimumRevision The microcode whose revision <=3D MinimumRev= ision is treated as invalid. + Caller can supply value get from GetProcesso= rMicrocodeSignature() to check + whether the microcode is newer than loaded o= ne. + Caller can supply 0 to treat any revision (e= xcept 0) microcode as valid. + @param MicrocodeCpuIds Pointer to an array of processor signature a= nd platform ID that represents + a set of processors. + Caller can supply zero-element array to skip= the processor signature and + platform ID check. + @param MicrocodeCpuIdCount The number of elements in MicrocodeCpuIds. + @param VerifyChecksum FALSE to skip all the checksum verifications= . + + @retval TRUE The microcode is valid. + @retval FALSE The microcode is invalid. +**/ +BOOLEAN +EFIAPI +IsValidMicrocode ( + IN CPU_MICROCODE_HEADER *Microcode, + IN UINTN MicrocodeLength, + IN UINT32 MinimumRevision, + IN EDKII_PEI_MICROCODE_CPU_ID *MicrocodeCpuIds, + IN UINTN MicrocodeCpuIdCount, + IN BOOLEAN VerifyChecksum + ) +{ + UINTN Index; + UINT32 DataSize; + UINT32 TotalSize; + CPU_MICROCODE_EXTENDED_TABLE *ExtendedTable; + CPU_MICROCODE_EXTENDED_TABLE_HEADER *ExtendedTableHeader; + UINT32 ExtendedTableLength; + UINT32 Sum32; + BOOLEAN Match; + + ASSERT (Microcode !=3D NULL); + + // + // It's invalid when: + // the input microcode buffer is so small that even cannot contain the= header. + // the input microcode buffer is so large that exceeds MAX_ADDRESS. + // + if ((MicrocodeLength < sizeof (CPU_MICROCODE_HEADER)) || (MicrocodeLengt= h > (MAX_ADDRESS - (UINTN) Microcode))) { + return FALSE; + } + + // + // Per SDM, HeaderVersion and LoaderRevision should both be 1. + // + if ((Microcode->HeaderVersion !=3D 1) || (Microcode->LoaderRevision !=3D= 1)) { + return FALSE; + } + + // + // The microcode revision should be larger than the minimum revision. + // + if (Microcode->UpdateRevision <=3D MinimumRevision) { + return FALSE; + } + + DataSize =3D Microcode->DataSize; + if (DataSize =3D=3D 0) { + DataSize =3D 2000; + } + + // + // Per SDM, DataSize should be multiple of DWORDs. + // + if ((DataSize % 4) !=3D 0) { + return FALSE; + } + + TotalSize =3D GetMicrocodeLength (Microcode); + + // + // Check whether the whole microcode is within the buffer. + // TotalSize should be multiple of 1024. + // + if (((TotalSize % SIZE_1KB) !=3D 0) || (TotalSize > MicrocodeLength)) { + return FALSE; + } + + // + // The summation of all DWORDs in microcode should be zero. + // + if (VerifyChecksum && (CalculateSum32 ((UINT32 *) Microcode, TotalSize) = !=3D 0)) { + return FALSE; + } + + Sum32 =3D Microcode->ProcessorSignature.Uint32 + Microcode->ProcessorFla= gs + Microcode->Checksum; + + // + // Check the processor signature and platform ID in the primary header. + // + Match =3D IsProcessorMatchedMicrocode ( + Microcode->ProcessorSignature.Uint32, + Microcode->ProcessorFlags, + MicrocodeCpuIds, + MicrocodeCpuIdCount + ); + if (Match) { + return TRUE; + } + + ExtendedTableLength =3D TotalSize - (DataSize + sizeof (CPU_MICROCODE_HE= ADER)); + if ((ExtendedTableLength < sizeof (CPU_MICROCODE_EXTENDED_TABLE_HEADER))= || ((ExtendedTableLength % 4) !=3D 0)) { + return FALSE; + } + // + // Extended Table exist, check if the CPU in support list + // + ExtendedTableHeader =3D (CPU_MICROCODE_EXTENDED_TABLE_HEADER *) ((UINTN)= (Microcode + 1) + DataSize); + if (ExtendedTableHeader->ExtendedSignatureCount > MAX_UINT32 / sizeof (C= PU_MICROCODE_EXTENDED_TABLE)) { + return FALSE; + } + if (ExtendedTableHeader->ExtendedSignatureCount * sizeof (CPU_MICROCODE_= EXTENDED_TABLE) + > ExtendedTableLength - sizeof (CPU_MICROCODE_EXTENDED_TABLE_HEADER)= ) { + return FALSE; + } + // + // Check the extended table checksum + // + if (VerifyChecksum && (CalculateSum32 ((UINT32 *) ExtendedTableHeader, E= xtendedTableLength) !=3D 0)) { + return FALSE; + } + + ExtendedTable =3D (CPU_MICROCODE_EXTENDED_TABLE *) (ExtendedTableHeader = + 1); + for (Index =3D 0; Index < ExtendedTableHeader->ExtendedSignatureCount; I= ndex ++) { + if (VerifyChecksum && + (ExtendedTable[Index].ProcessorSignature.Uint32 + ExtendedTable[In= dex].ProcessorFlag + + ExtendedTable[Index].Checksum !=3D Sum32)) { + // + // The extended table entry is valid when the summation of Processor= Signature, Processor Flags + // and Checksum equal to the coresponding summation from primary hea= der. Because: + // CalculateSum32 (Header + Update Binary) =3D=3D 0 + // CalculateSum32 (Header + Update Binary) + // - (Header.ProcessorSignature + Header.ProcessorFlag + Head= er.Checksum) + // + (Extended.ProcessorSignature + Extended.ProcessorFlag + = Extended.Checksum) =3D=3D 0 + // So, + // (Header.ProcessorSignature + Header.ProcessorFlag + Header.Che= cksum) + // =3D=3D (Extended.ProcessorSignature + Extended.ProcessorFlag = + Extended.Checksum) + // + continue; + } + Match =3D IsProcessorMatchedMicrocode ( + ExtendedTable[Index].ProcessorSignature.Uint32, + ExtendedTable[Index].ProcessorFlag, + MicrocodeCpuIds, + MicrocodeCpuIdCount + ); + if (Match) { + return TRUE; + } + } + return FALSE; +} diff --git a/UefiCpuPkg/Library/MicrocodeLib/MicrocodeLib.inf b/UefiCpuPkg/= Library/MicrocodeLib/MicrocodeLib.inf new file mode 100644 index 0000000000..c6f8f52e95 --- /dev/null +++ b/UefiCpuPkg/Library/MicrocodeLib/MicrocodeLib.inf @@ -0,0 +1,32 @@ +## @file +# Library for microcode verification and load. +# +# Copyright (c) 2021, Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +# +## + +[Defines] + INF_VERSION =3D 0x00010006 + BASE_NAME =3D MicrocodeLib + FILE_GUID =3D EB8C72BC-8A48-4F80-996B-E52F68416D57 + MODULE_TYPE =3D BASE + VERSION_STRING =3D 1.0 + LIBRARY_CLASS =3D MicrocodeLib + +# +# VALID_ARCHITECTURES =3D IA32 X64 EBC +# + +[Sources.common] + MicrocodeLib.c + +[Packages] + MdePkg/MdePkg.dec + UefiCpuPkg/UefiCpuPkg.dec + +[LibraryClasses] + BaseLib + DebugLib diff --git a/UefiCpuPkg/UefiCpuPkg.dec b/UefiCpuPkg/UefiCpuPkg.dec index a639ce5412..62acb291f3 100644 --- a/UefiCpuPkg/UefiCpuPkg.dec +++ b/UefiCpuPkg/UefiCpuPkg.dec @@ -1,7 +1,7 @@ ## @file UefiCpuPkg.dec # This Package provides UEFI compatible CPU modules and libraries. # -# Copyright (c) 2007 - 2020, Intel Corporation. All rights reserved.
+# Copyright (c) 2007 - 2021, Intel Corporation. All rights reserved.
# # SPDX-License-Identifier: BSD-2-Clause-Patent # @@ -59,6 +59,9 @@ [LibraryClasses.IA32, LibraryClasses.X64] ## @libraryclass Provides function to get CPU cache information. CpuCacheInfoLib|Include/Library/CpuCacheInfoLib.h =20 + ## @libraryclass Provides function for loading microcode. + MicrocodeLib|Include/Library/MicrocodeLib.h + [Guids] gUefiCpuPkgTokenSpaceGuid =3D { 0xac05bf33, 0x995a, 0x4ed4, { 0xaa,= 0xb8, 0xef, 0x7a, 0xe8, 0xf, 0x5c, 0xb0 }} gMsegSmramGuid =3D { 0x5802bce4, 0xeeee, 0x4e33, { 0xa1,= 0x30, 0xeb, 0xad, 0x27, 0xf0, 0xe4, 0x39 }} diff --git a/UefiCpuPkg/UefiCpuPkg.dsc b/UefiCpuPkg/UefiCpuPkg.dsc index 98c4c53465..b932cf63ec 100644 --- a/UefiCpuPkg/UefiCpuPkg.dsc +++ b/UefiCpuPkg/UefiCpuPkg.dsc @@ -60,6 +60,7 @@ [LibraryClasses] PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BasePeC= offExtraActionLibNull.inf TpmMeasurementLib|MdeModulePkg/Library/TpmMeasurementLibNull/TpmMeasurem= entLibNull.inf VmgExitLib|UefiCpuPkg/Library/VmgExitLibNull/VmgExitLibNull.inf + MicrocodeLib|UefiCpuPkg/Library/MicrocodeLib/MicrocodeLib.inf =20 [LibraryClasses.common.SEC] PlatformSecLib|UefiCpuPkg/Library/PlatformSecLibNull/PlatformSecLibNull.= inf --=20 2.27.0.windows.1