From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) by mx.groups.io with SMTP id smtpd.web08.7437.1618571855448932665 for ; Fri, 16 Apr 2021 04:17:45 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@intel.onmicrosoft.com header.s=selector2-intel-onmicrosoft-com header.b=lh3jA9uA; spf=temperror, err=parse error for token &{10 18 _spf.intel.com}: temporary DNS error (domain: intel.com, ip: 134.134.136.20, mailfrom: ray.ni@intel.com) IronPort-SDR: OSZFKZpPMynNh0/7YeM2mZ1SMiYyOoR37UOH7TXNzy+LjOORhSh3m6dT2I3B2GyCkANR+Iuysm ChHcOEM3rV0Q== X-IronPort-AV: E=McAfee;i="6200,9189,9955"; a="182151103" X-IronPort-AV: E=Sophos;i="5.82,226,1613462400"; d="scan'208";a="182151103" Received: from orsmga002.jf.intel.com ([10.7.209.21]) by orsmga101.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 16 Apr 2021 04:17:34 -0700 IronPort-SDR: ES26S1ECoYkQyq4hX7xeQvxTHnBE3nUAbeOGjT+p2lnAjYjxQCIee3MfxJTHVKQ0+Pcei98QFv zC/+NQbPZ4eA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.82,226,1613462400"; d="scan'208";a="399883830" Received: from orsmsx603.amr.corp.intel.com ([10.22.229.16]) by orsmga002.jf.intel.com with ESMTP; 16 Apr 2021 04:17:34 -0700 Received: from orsmsx602.amr.corp.intel.com (10.22.229.15) 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.2106.2; Fri, 16 Apr 2021 04:17:33 -0700 Received: from ORSEDG601.ED.cps.intel.com (10.7.248.6) 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; Fri, 16 Apr 2021 04:17:33 -0700 Received: from NAM12-BN8-obe.outbound.protection.outlook.com (104.47.55.169) 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.2106.2; Fri, 16 Apr 2021 04:17:33 -0700 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=m8JffWRCCqn3GVPETL6eIbS8TZGDEAS4i9pn5K16eMf6QFhFEWSUpkJamn7bWYcSUoDMJq4ad2iJ6eRuZ0jnjO7Kdc0PRWETuc+Ja5EBUnQFzzJZ7+riQB0PeRvtNIkKhPE8CNjmPNE5NxSqj0WE1gaThfLfOAHwfVFYT1yqexavuHJW9AGOQT72Tz6C0iei6V9GVP13ef+6UfLi4nBOolxnhW4wI+ZwRbdyN89YzWWLK9Rfy3ieA/0F1v0ImTB/BLUvnUQoih9nSO5gOGo16BSOAI4V0MoXaYZwFouX+3r/xm2n52UXro+16OlD7jY0lMH8C1cAyCsRIimu4MbMVw== 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=CHYYrYJL1NfySx+6UxVWdmSzF6DldnzV6oUr4tuceQY=; b=Lj3Rm9OVpvaaHAK1b+C/ilX+wRh+9LaU/4N1paKX8LITQdp+qwri3G0pp1Em6R8ec0ElU8nBEJF/v7W0uEpXP74jczgtGJrbX+65JF6Uy5W32HiGySqKUliLhL2Me/PxHngIBxioXsx1MFZlfVCQnHLCMCom3E/L8Z34PTkBZ5XeDDiDwnRcmB4sxtJVfGVH4SYuV0DrTXLQNcc7g3nOZ16t5/PlVgblyg1IiDEfbLa/eNoaK+sa0aUZ/2W6DoszDOmc/9jKW7U6f+nwh5eThVtY+z85Noq9KvX5EaZUPsrLfe9OXZW19aZmLFLKcNlRHX6HoefuaPHZWzAJQRgQ+g== 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=CHYYrYJL1NfySx+6UxVWdmSzF6DldnzV6oUr4tuceQY=; b=lh3jA9uA5KE83ao6YDnQE/7xlSmNeJWPI5IyTBB5nvJ2OdpLtsZ7F8A+MObN2t7Hmszl6B+iyi9a42yAqgbLA41ATZS3x+s9W9NB2kkgr1fSCp0PVYkiamZGr90zTSgdBVyzTEdbYKuH3T3vSaXf6Owx1L6Cj0/0ThxNeTbFZ9U= Received: from CO1PR11MB4930.namprd11.prod.outlook.com (2603:10b6:303:9b::11) by MWHPR11MB1408.namprd11.prod.outlook.com (2603:10b6:300:24::18) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4042.18; Fri, 16 Apr 2021 11:17:30 +0000 Received: from CO1PR11MB4930.namprd11.prod.outlook.com ([fe80::59d6:8b94:55bf:36e7]) by CO1PR11MB4930.namprd11.prod.outlook.com ([fe80::59d6:8b94:55bf:36e7%5]) with mapi id 15.20.4042.018; Fri, 16 Apr 2021 11:17:30 +0000 From: "Ni, Ray" To: "mikuback@linux.microsoft.com" , "devel@edk2.groups.io" , "Dong, Guo" CC: "Chaganty, Rangasai V" Subject: Re: [edk2-platforms][PATCH v1 10/35] IntelSiliconPkg: Add MM SPI FVB services Thread-Topic: [edk2-platforms][PATCH v1 10/35] IntelSiliconPkg: Add MM SPI FVB services Thread-Index: AQHXMmjOAxTg95XYwEyrJF8qiMJn4qq2/p5w Date: Fri, 16 Apr 2021 11:17:30 +0000 Message-ID: References: <20210416023152.771-1-mikuback@linux.microsoft.com> <20210416023152.771-11-mikuback@linux.microsoft.com> In-Reply-To: <20210416023152.771-11-mikuback@linux.microsoft.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: linux.microsoft.com; dkim=none (message not signed) header.d=none;linux.microsoft.com; dmarc=none action=none header.from=intel.com; x-originating-ip: [124.77.195.36] x-ms-publictraffictype: Email x-ms-office365-filtering-correlation-id: 1914c6ae-fd2b-4cb4-51df-08d900c939a8 x-ms-traffictypediagnostic: MWHPR11MB1408: x-ms-exchange-transport-forked: True x-microsoft-antispam-prvs: x-ms-oob-tlc-oobclassifiers: OLM:9508; x-ms-exchange-senderadcheck: 1 x-microsoft-antispam: BCL:0; x-microsoft-antispam-message-info: FKPMcmNukhgCYU2yPiEi61V0rgXXDTW7LH6zPW1+pbl7yfR2I3Tu2t0/FfTOMO0dfv8sPhMDQTG/0lMoVx5e4laxl0zGDis91uZGY7oMTvLYE3w1WJEJQDpV4c3ir99QK8Z7KEwP7nIdingA0Ypqqi9CCfqnxunkiWpJwItOszLPlM3mTVXD3ihrLc9BSs2uv7dtAN/xWz1WhYgmlWyNqKeSepigtUSxUAMKsaGbc9F6vZ64cYY7jGNKswojUCWL18qh4OWpXu+fhlUKgICH/9uIuQ4pwF3EZ5RtnHw0J7+mETgupV1hH0Av2ncyIuZ85MeIqEdcZCDRD6+OwQ9zKcGz4Xg6HQFMqdcGasfNCrnof89VkzMyh6t4A8wodqNwS76zW4NVXYtDKg+zIjzuFMaVYelLAUqIbopa624SJ86fMAWicMR0RwgTYRoMr8Uel46Lr29G+oxFdCQj9vtWutrhfx06qWCPOpca4hjAepwGzR1+NbJXSLYFdMhuy2+5v245jIa/WeT6hHppOkrFuX42CbaWuF+uDKkGNbpo/I6HlqaNGtmtCUo739jmIf/MeL1XBq3PIuwWW642LdVPD579zc61Hei9dFcPCksPZbrhMa9VuCTnylbMd4igjSSKUsuNMcZ8qxvWYQOOPKYcz0lYTtwI32EeHE/5jk3Snp6zF/e6rfpnFOiO4mlsrnBS 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:(39860400002)(366004)(346002)(136003)(376002)(396003)(110136005)(30864003)(26005)(19627235002)(53546011)(478600001)(66556008)(7696005)(33656002)(316002)(2906002)(122000001)(76116006)(86362001)(8936002)(45080400002)(52536014)(55016002)(6636002)(6506007)(107886003)(71200400001)(9686003)(4326008)(64756008)(8676002)(83380400001)(186003)(5660300002)(66446008)(66946007)(38100700002)(66476007)(579004)(559001);DIR:OUT;SFP:1102; x-ms-exchange-antispam-messagedata: =?us-ascii?Q?HjFXk4cSgtdTSVACZC/HUSkoU41F6lOsxcXmrOctkOBSykYMeB9lOlCDgXF9?= =?us-ascii?Q?KUjVgzxu+OGrSu+9C+duz39TVLpGSnjaVsfCXZ7r76qLY+IM0kvx2v+G5p2X?= =?us-ascii?Q?XvFzv8YXnwxxVMExjiF/v6ddZWvPq5qfTNtAN0a8+2duxFlChGfBTQi6ckzK?= =?us-ascii?Q?Mul7wWPNjO9shmI4DETe54GpdmvtrL07WbTXSx9wTKJdNRsl6U/vnBcm3O2/?= =?us-ascii?Q?3pOycx0QsUDe8Bi5ozHzq3FoyjN6jGTx9BU+V3rS9fP4p3hwTJzBjLbPk+D1?= =?us-ascii?Q?8nDrTv9YL4SqpoKhCjKCl8wk17O6hXKBRY0+gB/lfV7/hfCanhBfYwpWFRsi?= =?us-ascii?Q?Zi3TBC+bXA5+xu5scObTKwpTwOJHxgvqE1zrc69JjTSVxleLhL1gfBwdcDwL?= =?us-ascii?Q?Oml4CtnzhJoxpiL1E5b29Utu9/zbwWG+VTt+zdDqExtchrhwSyeJgY4t6SEk?= =?us-ascii?Q?FGX11xzTE5GmsWQ2e/+hICuq/uOhaUxqvx+Q2sfECjFQ49eqDfD72Rsnc1qi?= =?us-ascii?Q?fHv4fmlN4vHy8ZgheCJQiNRB1T/Wa1Vo8LMMUE3jlUuXHxZcT4Xjf5xKj3nf?= =?us-ascii?Q?RFPqn7CoQ0UrtFuyVD2Pv9k+DxYu/B10fy/KqenT3apOG/F+NfX8eYDpHOIe?= =?us-ascii?Q?YP8qFttR4wpYYpQmiUcIpDdX8HgOunamLzX98eCRXLNFfO9uO/oUyCGkNAQz?= =?us-ascii?Q?DnasQVjXnqApH477ef6nvZiaRfMa5bGiSkC1tRWGes7R0327avRg6oPZHaHM?= =?us-ascii?Q?wHKQ+ry1548bXIp3TFZRRjAZONx/JXPzeZVVSkDrYSJN/RHhxMHvqGMb89x4?= =?us-ascii?Q?p4WVEL9cS0MQGkWtkYCquCzpx0sqR6XNHdlXxogQcShHGiajOdSrfHsCm3xC?= =?us-ascii?Q?kEL4ICO30iXAR3FCs+YT33sfKTCEu9DED+HMCvLlfVp7XbYMOZpCzit6d8nw?= =?us-ascii?Q?MtywWTWXUPCUDABaUDW2T4TU4k6PcWWcrXmhb0d91r60iUBYbR18GvtCoD8+?= =?us-ascii?Q?kcSiPlcJ9bYLCBKEXiwrHCZTbW6OZP8qR4cQx8KN9boV8QMtMDHh8Nd9GCXt?= =?us-ascii?Q?YPnqVlTe/4vRg6wMI4cwih5hiyIaQ8zcIqC6uWN3MUo93LFxg+9EqeQL+goW?= =?us-ascii?Q?Axum5KjxFV1ug7f47Taj2NTLkJnTf7kZvjI587uYbFooi3mA733eN5muEZqE?= =?us-ascii?Q?IQyO+xI0H8DsenQ2XMw/GuwDwc7IxTS+W4beNyqsXnPfnFDZ/8mjrtrTHwcv?= =?us-ascii?Q?rDsarFcXY04BddvNFaOh3dhEtCg+yZDdNwfa2DVZQ8xT3iyAgiGH3XPwl65v?= =?us-ascii?Q?vN9idiFxOjAI0JdGzumWhWqZ?= 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: 1914c6ae-fd2b-4cb4-51df-08d900c939a8 X-MS-Exchange-CrossTenant-originalarrivaltime: 16 Apr 2021 11:17:30.3602 (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: 3hjYKhWnvQ+l0Q0On0uhcktO2SZQexDOFaJlxIyxk0WNGU2F90HNuKp+/xPin5aruJDuVBRcRegFUBZ8A1DhIQ== X-MS-Exchange-Transport-CrossTenantHeadersStamped: MWHPR11MB1408 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 Guo, I remember you mentioned to me there is a standard way to manipulate the fl= ash storage because there is a HW between the SW and the real flash that do= es the command translation. Is this change related to the standard way what you mentioned to me? If yes, can you please help to review and provide comments? Michael, Having a universal implementation for SPI access is wonderful! Can you plea= se share the documentation that explain the Intel Serial Flash Interface Co= mpatibility spec? > -----Original Message----- > From: mikuback@linux.microsoft.com > Sent: Friday, April 16, 2021 10:31 AM > To: devel@edk2.groups.io > Cc: Ni, Ray ; Chaganty, Rangasai V > Subject: [edk2-platforms][PATCH v1 10/35] IntelSiliconPkg: Add MM SPI FVB= services >=20 > From: Michael Kubacki >=20 > REF:https://bugzilla.tianocore.org/show_bug.cgi?id=3D3307 >=20 > Adds a Traditional MM and Standalone MM SPI FVB Service driver to > IntelSiliconPkg. These drivers produce the firmware volume block > protocol for SPI flash devices compliant with the Intel Serial > Flash Interface Compatibility Specification. >=20 > Cc: Ray Ni > Cc: Rangasai V Chaganty > Signed-off-by: Michael Kubacki > --- > Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/FvbInfo.c = | 94 ++ > Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbServiceC= ommon.c | 903 ++++++++++++++++++++ > Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbServiceM= m.c | 271 ++++++ > Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbServiceS= tandaloneMm.c | 32 + > Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbServiceT= raditionalMm.c | 32 + > Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbServiceC= ommon.h | 158 ++++ > Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbServiceM= m.h | 22 + > Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbServiceS= mm.inf | 68 ++ > Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbServiceS= tandaloneMm.inf | 67 ++ > Silicon/Intel/IntelSiliconPkg/IntelSiliconPkg.dsc = | 11 + > 10 files changed, 1658 insertions(+) >=20 > diff --git a/Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/Fv= bInfo.c > b/Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/FvbInfo.c > new file mode 100644 > index 000000000000..7f2678fa9e5a > --- /dev/null > +++ b/Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/FvbInfo.c > @@ -0,0 +1,94 @@ > +/**@file > + Defines data structure that is the volume header found. > + These data is intent to decouple FVB driver with FV header. > + > +Copyright (c) 2017, Intel Corporation. All rights reserved.
> +SPDX-License-Identifier: BSD-2-Clause-Patent > + > +**/ > + > +#include "SpiFvbServiceCommon.h" > + > +#define FIRMWARE_BLOCK_SIZE 0x10000 > +#define FVB_MEDIA_BLOCK_SIZE FIRMWARE_BLOCK_SIZE > + > +#define NV_STORAGE_BASE_ADDRESS FixedPcdGet32(PcdFlashNvStorageVaria= bleBase) > +#define SYSTEM_NV_BLOCK_NUM ((FixedPcdGet32(PcdFlashNvStorageVar= iableSize)+ > FixedPcdGet32(PcdFlashNvStorageFtwWorkingSize) + FixedPcdGet32(PcdFlashNv= StorageFtwSpareSize))/ > FVB_MEDIA_BLOCK_SIZE) > + > +typedef struct { > + EFI_PHYSICAL_ADDRESS BaseAddress; > + EFI_FIRMWARE_VOLUME_HEADER FvbInfo; > + EFI_FV_BLOCK_MAP_ENTRY End[1]; > +} EFI_FVB2_MEDIA_INFO; > + > +// > +// This data structure contains a template of all correct FV headers, wh= ich is used to restore > +// Fv header if it's corrupted. > +// > +EFI_FVB2_MEDIA_INFO mPlatformFvbMediaInfo[] =3D { > + // > + // Systen NvStorage FVB > + // > + { > + NV_STORAGE_BASE_ADDRESS, > + { > + {0,}, //ZeroVector[16] > + EFI_SYSTEM_NV_DATA_FV_GUID, > + FVB_MEDIA_BLOCK_SIZE * SYSTEM_NV_BLOCK_NUM, > + EFI_FVH_SIGNATURE, > + 0x0004feff, // check MdePkg/Include/Pi/PiFirmwareVolume.h for deta= ils on EFI_FVB_ATTRIBUTES_2 > + sizeof (EFI_FIRMWARE_VOLUME_HEADER) + sizeof (EFI_FV_BLOCK_MAP_ENT= RY), > + 0, //CheckSum which will be calucated dynamically. > + 0, //ExtHeaderOffset > + {0,}, //Reserved[1] > + 2, //Revision > + { > + { > + SYSTEM_NV_BLOCK_NUM, > + FVB_MEDIA_BLOCK_SIZE, > + } > + } > + }, > + { > + { > + 0, > + 0 > + } > + } > + } > +}; > + > +EFI_STATUS > +GetFvbInfo ( > + IN EFI_PHYSICAL_ADDRESS FvBaseAddress, > + OUT EFI_FIRMWARE_VOLUME_HEADER **FvbInfo > + ) > +{ > + UINTN Index; > + EFI_FIRMWARE_VOLUME_HEADER *FvHeader; > + > + for (Index =3D 0; Index < sizeof (mPlatformFvbMediaInfo) / sizeof (EFI= _FVB2_MEDIA_INFO); Index++) { > + if (mPlatformFvbMediaInfo[Index].BaseAddress =3D=3D FvBaseAddress) { > + FvHeader =3D &mPlatformFvbMediaInfo[Index].FvbInfo; > + > + // > + // Update the checksum value of FV header. > + // > + FvHeader->Checksum =3D CalculateCheckSum16 ( (UINT16 *) FvHeader, = FvHeader->HeaderLength); > + > + *FvbInfo =3D FvHeader; > + > + DEBUG ((DEBUG_INFO, "BaseAddr: 0x%lx \n", FvBaseAddress)); > + DEBUG ((DEBUG_INFO, "FvLength: 0x%lx \n", (*FvbInfo)->FvLength)); > + DEBUG ((DEBUG_INFO, "HeaderLength: 0x%x \n", (*FvbInfo)->HeaderLen= gth)); > + DEBUG ((DEBUG_INFO, "Header Checksum: 0x%X\n", (*FvbInfo)->Checksu= m)); > + DEBUG ((DEBUG_INFO, "FvBlockMap[0].NumBlocks: 0x%x \n", (*FvbInfo)= ->BlockMap[0].NumBlocks)); > + DEBUG ((DEBUG_INFO, "FvBlockMap[0].BlockLength: 0x%x \n", (*FvbInf= o)->BlockMap[0].Length)); > + DEBUG ((DEBUG_INFO, "FvBlockMap[1].NumBlocks: 0x%x \n", (*FvbInfo)= ->BlockMap[1].NumBlocks)); > + DEBUG ((DEBUG_INFO, "FvBlockMap[1].BlockLength: 0x%x \n\n", (*FvbI= nfo)->BlockMap[1].Length)); > + > + return EFI_SUCCESS; > + } > + } > + return EFI_NOT_FOUND; > +} > diff --git a/Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/Sp= iFvbServiceCommon.c > b/Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbService= Common.c > new file mode 100644 > index 000000000000..dab818e98087 > --- /dev/null > +++ b/Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbSer= viceCommon.c > @@ -0,0 +1,903 @@ > +/** @file > + Common driver source for several Serial Flash devices > + which are compliant with the Intel(R) Serial Flash Interface Compatibi= lity Specification. > + > +Copyright (c) 2017, Intel Corporation. All rights reserved.
> +SPDX-License-Identifier: BSD-2-Clause-Patent > + > +**/ > + > +#include "SpiFvbServiceCommon.h" > + > +// > +// Global variable for this FVB driver which contains > +// the private data of all firmware volume block instances > +// > +FVB_GLOBAL mFvbModuleGlobal; > + > +// > +// This platform driver knows there are multiple FVs on FD. > +// Now we only provide FVs on Variable region and MicorCode region for p= erformance issue. > +// > +FV_INFO mPlatformFvBaseAddress[] =3D { > + {0, 0}, // {FixedPcdGet32(PcdFlashNvStorageVariableBase), FixedPcdGet3= 2(PcdFlashNvStorageVariableSize)}, > + {0, 0}, // {FixedPcdGet32(PcdFlashMicrocodeFvBase), FixedPcdGet32(PcdF= lashMicrocodeFvSize)}, > + {0, 0} > +}; > + > +FV_INFO mPlatformDefaultBaseAddress[] =3D { > + {0, 0}, // {FixedPcdGet32(PcdFlashNvStorageVariableBase), FixedPcdGet3= 2(PcdFlashNvStorageVariableSize)}, > + {0, 0}, // {FixedPcdGet32(PcdFlashMicrocodeFvBase), FixedPcdGet32(PcdF= lashMicrocodeFvSize)}, > + {0, 0} > +}; > + > +FV_MEMMAP_DEVICE_PATH mFvMemmapDevicePathTemplate =3D { > + { > + { > + HARDWARE_DEVICE_PATH, > + HW_MEMMAP_DP, > + { > + (UINT8)(sizeof (MEMMAP_DEVICE_PATH)), > + (UINT8)(sizeof (MEMMAP_DEVICE_PATH) >> 8) > + } > + }, > + EfiMemoryMappedIO, > + (EFI_PHYSICAL_ADDRESS) 0, > + (EFI_PHYSICAL_ADDRESS) 0, > + }, > + { > + END_DEVICE_PATH_TYPE, > + END_ENTIRE_DEVICE_PATH_SUBTYPE, > + { > + END_DEVICE_PATH_LENGTH, > + 0 > + } > + } > +}; > + > +FV_PIWG_DEVICE_PATH mFvPIWGDevicePathTemplate =3D { > + { > + { > + MEDIA_DEVICE_PATH, > + MEDIA_PIWG_FW_VOL_DP, > + { > + (UINT8)(sizeof (MEDIA_FW_VOL_DEVICE_PATH)), > + (UINT8)(sizeof (MEDIA_FW_VOL_DEVICE_PATH) >> 8) > + } > + }, > + { 0 } > + }, > + { > + END_DEVICE_PATH_TYPE, > + END_ENTIRE_DEVICE_PATH_SUBTYPE, > + { > + END_DEVICE_PATH_LENGTH, > + 0 > + } > + } > +}; > + > +// > +// Template structure used when installing FVB protocol > +// > +EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL mFvbProtocolTemplate =3D { > + FvbProtocolGetAttributes, > + FvbProtocolSetAttributes, > + FvbProtocolGetPhysicalAddress, > + FvbProtocolGetBlockSize, > + FvbProtocolRead, > + FvbProtocolWrite, > + FvbProtocolEraseBlocks, > + NULL > +}; > + > +/** > + Get the EFI_FVB_ATTRIBUTES_2 of a FV. > + > + @param[in] FvbInstance The pointer to the EFI_FVB_INSTANCE. > + > + @return Attributes of the FV identified by FvbInstance. > + > +**/ > +EFI_FVB_ATTRIBUTES_2 > +FvbGetVolumeAttributes ( > + IN EFI_FVB_INSTANCE *FvbInstance > + ) > +{ > + return FvbInstance->FvHeader.Attributes; > +} > + > +/** > + Retrieves the starting address of an LBA in an FV. It also > + return a few other attribut of the FV. > + > + @param[in] FvbInstance The pointer to the EFI_FVB_INSTANCE. > + @param[in] Lba The logical block address > + @param[out] LbaAddress On output, contains the physical starting = address > + of the Lba > + @param[out] LbaLength On output, contains the length of the bloc= k > + @param[out] NumOfBlocks A pointer to a caller allocated UINTN in w= hich the > + number of consecutive blocks starting with= Lba is > + returned. All blocks in this range have a = size of > + BlockSize > + > + @retval EFI_SUCCESS Successfully returns > + @retval EFI_INVALID_PARAMETER Instance not found > + > +**/ > +EFI_STATUS > +FvbGetLbaAddress ( > + IN EFI_FVB_INSTANCE *FvbInstance, > + IN EFI_LBA Lba, > + OUT UINTN *LbaAddress, > + OUT UINTN *LbaLength, > + OUT UINTN *NumOfBlocks > + ) > +{ > + UINT32 NumBlocks; > + UINT32 BlockLength; > + UINTN Offset; > + EFI_LBA StartLba; > + EFI_LBA NextLba; > + EFI_FV_BLOCK_MAP_ENTRY *BlockMap; > + > + StartLba =3D 0; > + Offset =3D 0; > + BlockMap =3D &(FvbInstance->FvHeader.BlockMap[0]); > + > + // > + // Parse the blockmap of the FV to find which map entry the Lba belong= s to > + // > + while (TRUE) { > + NumBlocks =3D BlockMap->NumBlocks; > + BlockLength =3D BlockMap->Length; > + > + if ( NumBlocks =3D=3D 0 || BlockLength =3D=3D 0) { > + return EFI_INVALID_PARAMETER; > + } > + > + NextLba =3D StartLba + NumBlocks; > + > + // > + // The map entry found > + // > + if (Lba >=3D StartLba && Lba < NextLba) { > + Offset =3D Offset + (UINTN)MultU64x32((Lba - StartLba), BlockLengt= h); > + if (LbaAddress ) { > + *LbaAddress =3D FvbInstance->FvBase + Offset; > + } > + > + if (LbaLength ) { > + *LbaLength =3D BlockLength; > + } > + > + if (NumOfBlocks ) { > + *NumOfBlocks =3D (UINTN)(NextLba - Lba); > + } > + return EFI_SUCCESS; > + } > + > + StartLba =3D NextLba; > + Offset =3D Offset + NumBlocks * BlockLength; > + BlockMap++; > + } > +} > + > +/** > + Reads specified number of bytes into a buffer from the specified block= . > + > + @param[in] FvbInstance The pointer to the EFI_FVB_INSTA= NCE > + @param[in] Lba The logical block address to be = read from > + @param[in] BlockOffset Offset into the block at which t= o begin reading > + @param[in] NumBytes Pointer that on input contains t= he total size of > + the buffer. On output, it contai= ns the total number > + of bytes read > + @param[in] Buffer Pointer to a caller allocated bu= ffer that will be > + used to hold the data read > + > + > + @retval EFI_SUCCESS The firmware volume was read suc= cessfully and > + contents are in Buffer > + @retval EFI_BAD_BUFFER_SIZE Read attempted across a LBA boun= dary. On output, > + NumBytes contains the total numb= er of bytes returned > + in Buffer > + @retval EFI_ACCESS_DENIED The firmware volume is in the Re= adDisabled state > + @retval EFI_DEVICE_ERROR The block device is not function= ing correctly and > + could not be read > + @retval EFI_INVALID_PARAMETER Instance not found, or NumBytes,= Buffer are NULL > + > +**/ > +EFI_STATUS > +FvbReadBlock ( > + IN EFI_FVB_INSTANCE *FvbInstance, > + IN EFI_LBA Lba, > + IN UINTN BlockOffset, > + IN OUT UINTN *NumBytes, > + IN UINT8 *Buffer > + ) > +{ > + EFI_FVB_ATTRIBUTES_2 Attributes; > + UINTN LbaAddress; > + UINTN LbaLength; > + EFI_STATUS Status; > + BOOLEAN BadBufferSize =3D FALSE; > + > + if ((NumBytes =3D=3D NULL) || (Buffer =3D=3D NULL)) { > + return EFI_INVALID_PARAMETER; > + } > + if (*NumBytes =3D=3D 0) { > + return EFI_INVALID_PARAMETER; > + } > + > + Status =3D FvbGetLbaAddress (FvbInstance, Lba, &LbaAddress, &LbaLength= , NULL); > + if (EFI_ERROR(Status)) { > + return Status; > + } > + > + Attributes =3D FvbGetVolumeAttributes (FvbInstance); > + > + if ((Attributes & EFI_FVB2_READ_STATUS) =3D=3D 0) { > + return EFI_ACCESS_DENIED; > + } > + > + if (BlockOffset > LbaLength) { > + return EFI_INVALID_PARAMETER; > + } > + > + if (LbaLength < (*NumBytes + BlockOffset)) { > + DEBUG ((DEBUG_INFO, > + "FvReadBlock: Reducing Numbytes from 0x%x to 0x%x\n", > + *NumBytes, > + (UINT32)(LbaLength - BlockOffset)) > + ); > + *NumBytes =3D (UINT32) (LbaLength - BlockOffset); > + BadBufferSize =3D TRUE; > + } > + > + Status =3D SpiFlashRead (LbaAddress + BlockOffset, (UINT32 *)NumBytes,= Buffer); > + > + if (!EFI_ERROR (Status) && BadBufferSize) { > + return EFI_BAD_BUFFER_SIZE; > + } else { > + return Status; > + } > +} > + > +/** > + Writes specified number of bytes from the input buffer to the block. > + > + @param[in] FvbInstance The pointer to the EFI_FVB_INSTANCE > + @param[in] Lba The starting logical block index to = write to > + @param[in] BlockOffset Offset into the block at which to be= gin writing > + @param[in] NumBytes Pointer that on input contains the t= otal size of > + the buffer. On output, it contains t= he total number > + of bytes actually written > + @param[in] Buffer Pointer to a caller allocated buffer= that contains > + the source for the write > + @retval EFI_SUCCESS The firmware volume was written succ= essfully > + @retval EFI_BAD_BUFFER_SIZE Write attempted across a LBA boundar= y. On output, > + NumBytes contains the total number o= f bytes > + actually written > + @retval EFI_ACCESS_DENIED The firmware volume is in the WriteD= isabled state > + @retval EFI_DEVICE_ERROR The block device is not functioning = correctly and > + could not be written > + @retval EFI_INVALID_PARAMETER Instance not found, or NumBytes, Buf= fer are NULL > + > +**/ > +EFI_STATUS > +FvbWriteBlock ( > + IN EFI_FVB_INSTANCE *FvbInstance, > + IN EFI_LBA Lba, > + IN UINTN BlockOffset, > + IN OUT UINTN *NumBytes, > + IN UINT8 *Buffer > + ) > +{ > + EFI_FVB_ATTRIBUTES_2 Attributes; > + UINTN LbaAddress; > + UINTN LbaLength; > + EFI_STATUS Status; > + BOOLEAN BadBufferSize =3D FALSE; > + > + if ((NumBytes =3D=3D NULL) || (Buffer =3D=3D NULL)) { > + return EFI_INVALID_PARAMETER; > + } > + if (*NumBytes =3D=3D 0) { > + return EFI_INVALID_PARAMETER; > + } > + > + Status =3D FvbGetLbaAddress (FvbInstance, Lba, &LbaAddress, &LbaLength= , NULL); > + if (EFI_ERROR(Status)) { > + return Status; > + } > + > + // > + // Check if the FV is write enabled > + // > + Attributes =3D FvbGetVolumeAttributes (FvbInstance); > + if ((Attributes & EFI_FVB2_WRITE_STATUS) =3D=3D 0) { > + return EFI_ACCESS_DENIED; > + } > + > + // > + // Perform boundary checks and adjust NumBytes > + // > + if (BlockOffset > LbaLength) { > + return EFI_INVALID_PARAMETER; > + } > + > + if (LbaLength < (*NumBytes + BlockOffset)) { > + DEBUG ((DEBUG_INFO, > + "FvWriteBlock: Reducing Numbytes from 0x%x to 0x%x\n", > + *NumBytes, > + (UINT32)(LbaLength - BlockOffset)) > + ); > + *NumBytes =3D (UINT32) (LbaLength - BlockOffset); > + BadBufferSize =3D TRUE; > + } > + > + Status =3D SpiFlashWrite (LbaAddress + BlockOffset, (UINT32 *)NumBytes= , Buffer); > + if (EFI_ERROR (Status)) { > + return Status; > + } > + > + Status =3D SpiFlashLock (); > + if (EFI_ERROR (Status)) { > + return Status; > + } > + > + WriteBackInvalidateDataCacheRange ((VOID *) (LbaAddress + BlockOffset)= , *NumBytes); > + > + if (!EFI_ERROR (Status) && BadBufferSize) { > + return EFI_BAD_BUFFER_SIZE; > + } else { > + return Status; > + } > +} > + > + > + > +/** > + Erases and initializes a firmware volume block. > + > + @param[in] FvbInstance The pointer to the EFI_FVB_INSTANCE > + @param[in] Lba The logical block index to be erased > + > + @retval EFI_SUCCESS The erase request was successfully com= pleted > + @retval EFI_ACCESS_DENIED The firmware volume is in the WriteDis= abled state > + @retval EFI_DEVICE_ERROR The block device is not functioning co= rrectly and > + could not be written. Firmware device = may have been > + partially erased > + @retval EFI_INVALID_PARAMETER Instance not found > + > +**/ > +EFI_STATUS > +FvbEraseBlock ( > + IN EFI_FVB_INSTANCE *FvbInstance, > + IN EFI_LBA Lba > + ) > +{ > + > + EFI_FVB_ATTRIBUTES_2 Attributes; > + UINTN LbaAddress; > + UINTN LbaLength; > + EFI_STATUS Status; > + > + // > + // Check if the FV is write enabled > + // > + Attributes =3D FvbGetVolumeAttributes (FvbInstance); > + > + if( (Attributes & EFI_FVB2_WRITE_STATUS) =3D=3D 0) { > + return EFI_ACCESS_DENIED; > + } > + > + // > + // Get the starting address of the block for erase. > + // > + Status =3D FvbGetLbaAddress (FvbInstance, Lba, &LbaAddress, &LbaLength= , NULL); > + if (EFI_ERROR(Status)) { > + return Status; > + } > + > + Status =3D SpiFlashBlockErase (LbaAddress, &LbaLength); > + if (EFI_ERROR (Status)) { > + return Status; > + } > + > + Status =3D SpiFlashLock (); > + if (EFI_ERROR (Status)) { > + return Status; > + } > + > + WriteBackInvalidateDataCacheRange ((VOID *) LbaAddress, LbaLength); > + > + return Status; > +} > + > +/** > + Modifies the current settings of the firmware volume according to the > + input parameter, and returns the new setting of the volume > + > + @param[in] FvbInstance The pointer to the EFI_FVB_INSTANCE. > + @param[in] Attributes On input, it is a pointer to EFI_FVB= _ATTRIBUTES_2 > + containing the desired firmware volu= me settings. > + On successful return, it contains th= e new settings > + of the firmware volume > + > + @retval EFI_SUCCESS Successfully returns > + @retval EFI_ACCESS_DENIED The volume setting is locked and can= not be modified > + @retval EFI_INVALID_PARAMETER Instance not found, or The attribute= s requested are > + in conflict with the capabilities as= declared in the > + firmware volume header > + > +**/ > +EFI_STATUS > +FvbSetVolumeAttributes ( > + IN EFI_FVB_INSTANCE *FvbInstance, > + IN OUT EFI_FVB_ATTRIBUTES_2 *Attributes > + ) > +{ > + EFI_FVB_ATTRIBUTES_2 OldAttributes; > + EFI_FVB_ATTRIBUTES_2 *AttribPtr; > + EFI_FVB_ATTRIBUTES_2 UnchangedAttributes; > + UINT32 Capabilities; > + UINT32 OldStatus, NewStatus; > + > + AttribPtr =3D (EFI_FVB_ATTRIBUTES_2 *) &(FvbInstance->FvHeader.Att= ributes); > + OldAttributes =3D *AttribPtr; > + Capabilities =3D OldAttributes & EFI_FVB2_CAPABILITIES; > + OldStatus =3D OldAttributes & EFI_FVB2_STATUS; > + NewStatus =3D *Attributes & EFI_FVB2_STATUS; > + > + UnchangedAttributes =3D EFI_FVB2_READ_DISABLED_CAP | \ > + EFI_FVB2_READ_ENABLED_CAP | \ > + EFI_FVB2_WRITE_DISABLED_CAP | \ > + EFI_FVB2_WRITE_ENABLED_CAP | \ > + EFI_FVB2_LOCK_CAP | \ > + EFI_FVB2_STICKY_WRITE | \ > + EFI_FVB2_MEMORY_MAPPED | \ > + EFI_FVB2_ERASE_POLARITY | \ > + EFI_FVB2_READ_LOCK_CAP | \ > + EFI_FVB2_WRITE_LOCK_CAP | \ > + EFI_FVB2_ALIGNMENT; > + > + // > + // Some attributes of FV is read only can *not* be set > + // > + if ((OldAttributes & UnchangedAttributes) ^ (*Attributes & UnchangedAt= tributes)) { > + return EFI_INVALID_PARAMETER; > + } > + > + // > + // If firmware volume is locked, no status bit can be updated > + // > + if ( OldAttributes & EFI_FVB2_LOCK_STATUS ) { > + if ( OldStatus ^ NewStatus ) { > + return EFI_ACCESS_DENIED; > + } > + } > + > + // > + // Test read disable > + // > + if ((Capabilities & EFI_FVB2_READ_DISABLED_CAP) =3D=3D 0) { > + if ((NewStatus & EFI_FVB2_READ_STATUS) =3D=3D 0) { > + return EFI_INVALID_PARAMETER; > + } > + } > + > + // > + // Test read enable > + // > + if ((Capabilities & EFI_FVB2_READ_ENABLED_CAP) =3D=3D 0) { > + if (NewStatus & EFI_FVB2_READ_STATUS) { > + return EFI_INVALID_PARAMETER; > + } > + } > + > + // > + // Test write disable > + // > + if ((Capabilities & EFI_FVB2_WRITE_DISABLED_CAP) =3D=3D 0) { > + if ((NewStatus & EFI_FVB2_WRITE_STATUS) =3D=3D 0) { > + return EFI_INVALID_PARAMETER; > + } > + } > + > + // > + // Test write enable > + // > + if ((Capabilities & EFI_FVB2_WRITE_ENABLED_CAP) =3D=3D 0) { > + if (NewStatus & EFI_FVB2_WRITE_STATUS) { > + return EFI_INVALID_PARAMETER; > + } > + } > + > + // > + // Test lock > + // > + if ((Capabilities & EFI_FVB2_LOCK_CAP) =3D=3D 0) { > + if (NewStatus & EFI_FVB2_LOCK_STATUS) { > + return EFI_INVALID_PARAMETER; > + } > + } > + > + *AttribPtr =3D (*AttribPtr) & (0xFFFFFFFF & (~EFI_FVB2_STATUS)); > + *AttribPtr =3D (*AttribPtr) | NewStatus; > + *Attributes =3D *AttribPtr; > + > + return EFI_SUCCESS; > +} > + > +/** > + Check the integrity of firmware volume header > + > + @param[in] FvHeader A pointer to a firmware volume header > + > + @retval TRUE The firmware volume is consistent > + @retval FALSE The firmware volume has corrupted. > + > +**/ > +BOOLEAN > +IsFvHeaderValid ( > + IN EFI_PHYSICAL_ADDRESS FvBase, > + IN CONST EFI_FIRMWARE_VOLUME_HEADER *FvHeader > + ) > +{ > + if (FvBase =3D=3D PcdGet32(PcdFlashNvStorageVariableBase)) { > + if (CompareMem (&FvHeader->FileSystemGuid, &gEfiSystemNvDataFvGuid, = sizeof(EFI_GUID)) !=3D 0 ) { > + return FALSE; > + } > + } else { > + if (CompareMem (&FvHeader->FileSystemGuid, &gEfiFirmwareFileSystem2G= uid, sizeof(EFI_GUID)) !=3D 0 ) { > + return FALSE; > + } > + } > + if ( (FvHeader->Revision !=3D EFI_FVH_REVISION) || > + (FvHeader->Signature !=3D EFI_FVH_SIGNATURE) || > + (FvHeader->FvLength =3D=3D ((UINTN) -1)) || > + ((FvHeader->HeaderLength & 0x01 ) !=3D0) ) { > + return FALSE; > + } > + > + if (CalculateCheckSum16 ((UINT16 *) FvHeader, FvHeader->HeaderLength) = !=3D 0) { > + return FALSE; > + } > + > + return TRUE; > +} > + > +// > +// FVB protocol APIs > +// > + > +/** > + Retrieves the physical address of the device. > + > + @param[in] This A pointer to EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL. > + @param[out] Address Output buffer containing the address. > + > + retval EFI_SUCCESS The function always return successfully. > + > +**/ > +EFI_STATUS > +EFIAPI > +FvbProtocolGetPhysicalAddress ( > + IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, > + OUT EFI_PHYSICAL_ADDRESS *Address > + ) > +{ > + EFI_FVB_INSTANCE *FvbInstance; > + > + FvbInstance =3D FVB_INSTANCE_FROM_THIS (This); > + > + *Address =3D FvbInstance->FvBase; > + > + return EFI_SUCCESS; > +} > + > +/** > + Retrieve the size of a logical block > + > + @param[in] This Calling context > + @param[in] Lba Indicates which block to return the size for. > + @param[out] BlockSize A pointer to a caller allocated UINTN in which > + the size of the block is returned > + @param[out] NumOfBlocks A pointer to a caller allocated UINTN in which= the > + number of consecutive blocks starting with Lba= is > + returned. All blocks in this range have a size= of > + BlockSize > + > + @retval EFI_SUCCESS The function always return successfully. > + > +**/ > +EFI_STATUS > +EFIAPI > +FvbProtocolGetBlockSize ( > + IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, > + IN EFI_LBA Lba, > + OUT UINTN *BlockSize, > + OUT UINTN *NumOfBlocks > + ) > +{ > + EFI_FVB_INSTANCE *FvbInstance; > + > + FvbInstance =3D FVB_INSTANCE_FROM_THIS (This); > + > + DEBUG((DEBUG_INFO, > + "FvbProtocolGetBlockSize: Lba: 0x%lx BlockSize: 0x%x NumOfBlocks: 0x= %x\n", > + Lba, > + BlockSize, > + NumOfBlocks) > + ); > + > + return FvbGetLbaAddress ( > + FvbInstance, > + Lba, > + NULL, > + BlockSize, > + NumOfBlocks > + ); > +} > + > +/** > + Retrieves Volume attributes. No polarity translations are done. > + > + @param[in] This Calling context > + @param[out] Attributes Output buffer which contains attributes > + > + @retval EFI_SUCCESS The function always return successfully. > + > +**/ > +EFI_STATUS > +EFIAPI > +FvbProtocolGetAttributes ( > + IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, > + OUT EFI_FVB_ATTRIBUTES_2 *Attributes > + ) > +{ > + EFI_FVB_INSTANCE *FvbInstance; > + > + FvbInstance =3D FVB_INSTANCE_FROM_THIS (This); > + > + *Attributes =3D FvbGetVolumeAttributes (FvbInstance); > + > + DEBUG ((DEBUG_INFO, > + "FvbProtocolGetAttributes: This: 0x%x Attributes: 0x%x\n", > + This, > + *Attributes) > + ); > + > + return EFI_SUCCESS; > +} > + > +/** > + Sets Volume attributes. No polarity translations are done. > + > + @param[in] This Calling context > + @param[out] Attributes Output buffer which contains attributes > + > + @retval EFI_SUCCESS The function always return successfully. > + > +**/ > +EFI_STATUS > +EFIAPI > +FvbProtocolSetAttributes ( > + IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, > + IN OUT EFI_FVB_ATTRIBUTES_2 *Attributes > + ) > +{ > + EFI_STATUS Status; > + EFI_FVB_INSTANCE *FvbInstance; > + > + DEBUG((DEBUG_INFO, > + "FvbProtocolSetAttributes: Before SET - This: 0x%x Attributes: 0x%x= \n", > + This, > + *Attributes) > + ); > + > + FvbInstance =3D FVB_INSTANCE_FROM_THIS (This); > + > + Status =3D FvbSetVolumeAttributes (FvbInstance, Attributes); > + > + DEBUG((DEBUG_INFO, > + "FvbProtocolSetAttributes: After SET - This: 0x%x Attributes: 0x%x\= n", > + This, > + *Attributes) > + ); > + > + return Status; > +} > + > +/** > + The EraseBlock() function erases one or more blocks as denoted by the > + variable argument list. The entire parameter list of blocks must be ve= rified > + prior to erasing any blocks. If a block is requested that does not ex= ist > + within the associated firmware volume (it has a larger index than the = last > + block of the firmware volume), the EraseBlock() function must return > + EFI_INVALID_PARAMETER without modifying the contents of the firmware v= olume. > + > + @param[in] This Calling context > + @param[in] ... Starting LBA followed by Number of Lba to eras= e. > + a -1 to terminate the list. > + > + @retval EFI_SUCCESS The erase request was successfully completed > + @retval EFI_ACCESS_DENIED The firmware volume is in the WriteDisabled = state > + @retval EFI_DEVICE_ERROR The block device is not functioning correctl= y and > + could not be written. Firmware device may ha= ve been > + partially erased > + > +**/ > +EFI_STATUS > +EFIAPI > +FvbProtocolEraseBlocks ( > + IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, > + ... > + ) > +{ > + EFI_FVB_INSTANCE *FvbInstance; > + UINTN NumOfBlocks; > + VA_LIST Args; > + EFI_LBA StartingLba; > + UINTN NumOfLba; > + EFI_STATUS Status; > + > + DEBUG((DEBUG_INFO, "FvbProtocolEraseBlocks: \n")); > + > + FvbInstance =3D FVB_INSTANCE_FROM_THIS (This); > + > + NumOfBlocks =3D FvbInstance->NumOfBlocks; > + > + VA_START (Args, This); > + > + do { > + StartingLba =3D VA_ARG (Args, EFI_LBA); > + if ( StartingLba =3D=3D EFI_LBA_LIST_TERMINATOR ) { > + break; > + } > + > + NumOfLba =3D VA_ARG (Args, UINT32); > + > + // > + // Check input parameters > + // > + if (NumOfLba =3D=3D 0) { > + VA_END (Args); > + return EFI_INVALID_PARAMETER; > + } > + > + if ( ( StartingLba + NumOfLba ) > NumOfBlocks ) { > + return EFI_INVALID_PARAMETER; > + } > + } while ( 1 ); > + > + VA_END (Args); > + > + VA_START (Args, This); > + do { > + StartingLba =3D VA_ARG (Args, EFI_LBA); > + if (StartingLba =3D=3D EFI_LBA_LIST_TERMINATOR) { > + break; > + } > + > + NumOfLba =3D VA_ARG (Args, UINT32); > + > + while ( NumOfLba > 0 ) { > + Status =3D FvbEraseBlock (FvbInstance, StartingLba); > + if ( EFI_ERROR(Status)) { > + VA_END (Args); > + return Status; > + } > + StartingLba ++; > + NumOfLba --; > + } > + > + } while ( 1 ); > + > + VA_END (Args); > + > + return EFI_SUCCESS; > +} > + > +/** > + Writes data beginning at Lba:Offset from FV. The write terminates eith= er > + when *NumBytes of data have been written, or when a block boundary is > + reached. *NumBytes is updated to reflect the actual number of bytes > + written. The write opertion does not include erase. This routine will > + attempt to write only the specified bytes. If the writes do not stick, > + it will return an error. > + > + @param[in] This Calling context > + @param[in] Lba Block in which to begin write > + @param[in] Offset Offset in the block at which to begin write > + @param[in,out] NumBytes On input, indicates the requested write size= . On > + output, indicates the actual number of bytes= written > + @param[in] Buffer Buffer containing source data for the write. > + > + @retval EFI_SUCCESS The firmware volume was written successf= ully > + @retval EFI_BAD_BUFFER_SIZE Write attempted across a LBA boundary. O= n output, > + NumBytes contains the total number of by= tes > + actually written > + @retval EFI_ACCESS_DENIED The firmware volume is in the WriteDisab= led state > + @retval EFI_DEVICE_ERROR The block device is not functioning corr= ectly and > + could not be written > + @retval EFI_INVALID_PARAMETER NumBytes or Buffer are NULL > + > +**/ > +EFI_STATUS > +EFIAPI > +FvbProtocolWrite ( > + IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, > + IN EFI_LBA Lba, > + IN UINTN Offset, > + IN OUT UINTN *NumBytes, > + IN UINT8 *Buffer > + ) > +{ > + EFI_FVB_INSTANCE *FvbInstance; > + > + FvbInstance =3D FVB_INSTANCE_FROM_THIS (This); > + > + DEBUG((DEBUG_INFO, > + "FvbProtocolWrite: Lba: 0x%lx Offset: 0x%x NumBytes: 0x%x, Buffer: 0= x%x\n", > + Lba, > + Offset, > + *NumBytes, > + Buffer) > + ); > + > + return FvbWriteBlock (FvbInstance, Lba, Offset, NumBytes, Buffer); > +} > + > +/** > + Reads data beginning at Lba:Offset from FV. The Read terminates either > + when *NumBytes of data have been read, or when a block boundary is > + reached. *NumBytes is updated to reflect the actual number of bytes > + written. The write opertion does not include erase. This routine will > + attempt to write only the specified bytes. If the writes do not stick, > + it will return an error. > + > + @param[in] This Calling context > + @param[in] Lba Block in which to begin write > + @param[in] Offset Offset in the block at which to begin write > + @param[in,out] NumBytes On input, indicates the requested write size= . On > + output, indicates the actual number of bytes= written > + @param[in] Buffer Buffer containing source data for the write. > + > + @retval EFI_SUCCESS The firmware volume was read successfull= y and > + contents are in Buffer > + @retval EFI_BAD_BUFFER_SIZE Read attempted across a LBA boundary. On= output, > + NumBytes contains the total number of by= tes returned > + in Buffer > + @retval EFI_ACCESS_DENIED The firmware volume is in the ReadDisabl= ed state > + @retval EFI_DEVICE_ERROR The block device is not functioning corr= ectly and > + could not be read > + @retval EFI_INVALID_PARAMETER NumBytes or Buffer are NULL > + > +**/ > +EFI_STATUS > +EFIAPI > +FvbProtocolRead ( > + IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, > + IN EFI_LBA Lba, > + IN UINTN Offset, > + IN OUT UINTN *NumBytes, > + OUT UINT8 *Buffer > + ) > +{ > + EFI_FVB_INSTANCE *FvbInstance; > + EFI_STATUS Status; > + > + FvbInstance =3D FVB_INSTANCE_FROM_THIS (This); > + Status =3D FvbReadBlock (FvbInstance, Lba, Offset, NumBytes, Buffer); > + DEBUG((DEBUG_INFO, > + "FvbProtocolRead: Lba: 0x%lx Offset: 0x%x NumBytes: 0x%x, Buffer: 0x= %x\n", > + Lba, > + Offset, > + *NumBytes, > + Buffer) > + ); > + > + return Status; > +} > diff --git a/Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/Sp= iFvbServiceMm.c > b/Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbService= Mm.c > new file mode 100644 > index 000000000000..42a0828c6fae > --- /dev/null > +++ b/Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbSer= viceMm.c > @@ -0,0 +1,271 @@ > +/** @file > + MM driver source for several Serial Flash devices > + which are compliant with the Intel(R) Serial Flash Interface Compatibi= lity Specification. > + > + Copyright (c) 2017, Intel Corporation. All rights reserved.
> + Copyright (c) Microsoft Corporation.
> + SPDX-License-Identifier: BSD-2-Clause-Patent > + > +**/ > + > +#include "SpiFvbServiceCommon.h" > +#include > +#include > +#include > + > +/** > + The function installs EFI_FIRMWARE_VOLUME_BLOCK protocol > + for each FV in the system. > + > + @param[in] FvbInstance The pointer to a FW volume instance structur= e, > + which contains the information about one FV. > + > + @retval VOID > + > +**/ > +VOID > +InstallFvbProtocol ( > + IN EFI_FVB_INSTANCE *FvbInstance > + ) > +{ > + EFI_FIRMWARE_VOLUME_HEADER *FvHeader; > + EFI_STATUS Status; > + EFI_HANDLE FvbHandle; > + > + ASSERT (FvbInstance !=3D NULL); > + if (FvbInstance =3D=3D NULL) { > + return; > + } > + > + CopyMem (&FvbInstance->FvbProtocol, &mFvbProtocolTemplate, sizeof (EFI= _FIRMWARE_VOLUME_BLOCK_PROTOCOL)); > + > + FvHeader =3D &FvbInstance->FvHeader; > + if (FvHeader =3D=3D NULL) { > + return; > + } > + > + // > + // Set up the devicepath > + // > + DEBUG ((DEBUG_INFO, "FwBlockService.c: Setting up DevicePath for 0x%lx= :\n", FvbInstance->FvBase)); > + if (FvHeader->ExtHeaderOffset =3D=3D 0) { > + // > + // FV does not contains extension header, then produce MEMMAP_DEVICE= _PATH > + // > + FvbInstance->DevicePath =3D (EFI_DEVICE_PATH_PROTOCOL *) AllocateRun= timeCopyPool (sizeof > (FV_MEMMAP_DEVICE_PATH), &mFvMemmapDevicePathTemplate); > + if (FvbInstance->DevicePath =3D=3D NULL) { > + DEBUG ((DEBUG_INFO, "SpiFvbServiceSmm.c: Memory allocation for MEM= MAP_DEVICE_PATH failed\n")); > + return; > + } > + ((FV_MEMMAP_DEVICE_PATH *) FvbInstance->DevicePath)->MemMapDevPath.S= tartingAddress =3D FvbInstance->FvBase; > + ((FV_MEMMAP_DEVICE_PATH *) FvbInstance->DevicePath)->MemMapDevPath.E= ndingAddress =3D FvbInstance->FvBase + > FvHeader->FvLength - 1; > + } else { > + FvbInstance->DevicePath =3D (EFI_DEVICE_PATH_PROTOCOL *) AllocateRun= timeCopyPool (sizeof (FV_PIWG_DEVICE_PATH), > &mFvPIWGDevicePathTemplate); > + if (FvbInstance->DevicePath =3D=3D NULL) { > + DEBUG ((DEBUG_INFO, "SpiFvbServiceSmm.c: Memory allocation for FV_= PIWG_DEVICE_PATH failed\n")); > + return; > + } > + CopyGuid ( > + &((FV_PIWG_DEVICE_PATH *)FvbInstance->DevicePath)->FvDevPath.FvNam= e, > + (GUID *)(UINTN)(FvbInstance->FvBase + FvHeader->ExtHeaderOffset) > + ); > + } > + > + // > + // LocateDevicePath fails so install a new interface and device path > + // > + FvbHandle =3D NULL; > + > + Status =3D gMmst->MmInstallProtocolInterface ( > + &FvbHandle, > + &gEfiSmmFirmwareVolumeBlockProtocolGuid, > + EFI_NATIVE_INTERFACE, > + &(FvbInstance->FvbProtocol) > + ); > + ASSERT_EFI_ERROR (Status); > + > + Status =3D gMmst->MmInstallProtocolInterface ( > + &FvbHandle, > + &gEfiDevicePathProtocolGuid, > + EFI_NATIVE_INTERFACE, > + &(FvbInstance->DevicePath) > + ); > + ASSERT_EFI_ERROR (Status); > +} > + > +/** > + The function does the necessary initialization work for > + Firmware Volume Block Driver. > + > +**/ > +VOID > +FvbInitialize ( > + VOID > + ) > +{ > + EFI_FVB_INSTANCE *FvbInstance; > + EFI_FIRMWARE_VOLUME_HEADER *FvHeader; > + EFI_FV_BLOCK_MAP_ENTRY *PtrBlockMapEntry; > + EFI_PHYSICAL_ADDRESS BaseAddress; > + EFI_STATUS Status; > + UINTN BufferSize; > + UINTN Idx; > + UINT32 MaxLbaSize; > + UINT32 BytesWritten; > + UINTN BytesErased; > + > + mPlatformFvBaseAddress[0].FvBase =3D PcdGet32(PcdFlashNvStorageVariabl= eBase); > + mPlatformFvBaseAddress[0].FvSize =3D PcdGet32(PcdFlashNvStorageVariabl= eSize); > + mPlatformFvBaseAddress[1].FvBase =3D PcdGet32(PcdFlashMicrocodeFvBase)= ; > + mPlatformFvBaseAddress[1].FvSize =3D PcdGet32(PcdFlashMicrocodeFvSize)= ; > + mPlatformDefaultBaseAddress[0].FvBase =3D PcdGet32(PcdFlashNvStorageVa= riableBase); > + mPlatformDefaultBaseAddress[0].FvSize =3D PcdGet32(PcdFlashNvStorageVa= riableSize); > + mPlatformDefaultBaseAddress[1].FvBase =3D PcdGet32(PcdFlashMicrocodeFv= Base); > + mPlatformDefaultBaseAddress[1].FvSize =3D PcdGet32(PcdFlashMicrocodeFv= Size); > + > + // > + // We will only continue with FVB installation if the > + // SPI is the active BIOS state > + // > + { > + // > + // Make sure all FVB are valid and/or fix if possible > + // > + for (Idx =3D 0;; Idx++) { > + if (mPlatformFvBaseAddress[Idx].FvSize =3D=3D 0 && mPlatformFvBase= Address[Idx].FvBase =3D=3D 0) { > + break; > + } > + > + BaseAddress =3D mPlatformFvBaseAddress[Idx].FvBase; > + FvHeader =3D (EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) BaseAddress; > + > + if (!IsFvHeaderValid (BaseAddress, FvHeader)) { > + BytesWritten =3D 0; > + BytesErased =3D 0; > + DEBUG ((DEBUG_ERROR, "ERROR - The FV in 0x%x is invalid!\n", FvH= eader)); > + Status =3D GetFvbInfo (BaseAddress, &FvHeader); > + if (EFI_ERROR (Status)) { > + DEBUG ((DEBUG_WARN, "ERROR - Can't recovery FV header at 0x%x.= GetFvbInfo Status %r\n", BaseAddress, Status)); > + continue; > + } > + DEBUG ((DEBUG_INFO, "Rewriting FV header at 0x%X with static dat= a\n", BaseAddress)); > + // > + // Spi erase > + // > + BytesErased =3D (UINTN) FvHeader->BlockMap->Length; > + Status =3D SpiFlashBlockErase( (UINTN) BaseAddress, &BytesErased= ); > + if (EFI_ERROR (Status)) { > + DEBUG ((DEBUG_WARN, "ERROR - SpiFlashBlockErase Error %r\n", = Status)); > + continue; > + } > + if (BytesErased !=3D FvHeader->BlockMap->Length) { > + DEBUG ((DEBUG_WARN, "ERROR - BytesErased !=3D FvHeader->BlockM= ap->Length\n")); > + DEBUG ((DEBUG_INFO, " BytesErased =3D 0x%X\n Length =3D 0x%X\n= ", BytesErased, FvHeader->BlockMap->Length)); > + continue; > + } > + BytesWritten =3D FvHeader->HeaderLength; > + Status =3D SpiFlashWrite ((UINTN)BaseAddress, &BytesWritten, (UI= NT8*)FvHeader); > + if (EFI_ERROR (Status)) { > + DEBUG ((DEBUG_WARN, "ERROR - SpiFlashWrite Error %r\n", Statu= s)); > + continue; > + } > + if (BytesWritten !=3D FvHeader->HeaderLength) { > + DEBUG ((DEBUG_WARN, "ERROR - BytesWritten !=3D HeaderLength\n"= )); > + DEBUG ((DEBUG_INFO, " BytesWritten =3D 0x%X\n HeaderLength =3D= 0x%X\n", BytesWritten, FvHeader->HeaderLength)); > + continue; > + } > + Status =3D SpiFlashLock (); > + if (EFI_ERROR (Status)) { > + DEBUG ((DEBUG_WARN, "ERROR - SpiFlashLock Error %r\n", Status= )); > + continue; > + } > + DEBUG ((DEBUG_INFO, "FV Header @ 0x%X restored with static data\= n", BaseAddress)); > + // > + // Clear cache for this range. > + // > + WriteBackInvalidateDataCacheRange ( (VOID *) (UINTN) BaseAddress= , FvHeader->BlockMap->Length); > + } > + } > + > + // > + // Calculate the total size for all firmware volume block instances > + // > + BufferSize =3D 0; > + for (Idx =3D 0; ; Idx++) { > + if (mPlatformFvBaseAddress[Idx].FvSize =3D=3D 0 && mPlatformFvBase= Address[Idx].FvBase =3D=3D 0) { > + break; > + } > + BaseAddress =3D mPlatformFvBaseAddress[Idx].FvBase; > + FvHeader =3D (EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) BaseAddress; > + > + if (!IsFvHeaderValid (BaseAddress, FvHeader)) { > + DEBUG ((DEBUG_WARN, "ERROR - The FV in 0x%x is invalid!\n", FvHe= ader)); > + continue; > + } > + > + BufferSize +=3D (FvHeader->HeaderLength + > + sizeof (EFI_FVB_INSTANCE) - > + sizeof (EFI_FIRMWARE_VOLUME_HEADER) > + ); > + } > + > + mFvbModuleGlobal.FvbInstance =3D (EFI_FVB_INSTANCE *) AllocateRunti= meZeroPool (BufferSize); > + if (mFvbModuleGlobal.FvbInstance =3D=3D NULL) { > + ASSERT (FALSE); > + return; > + } > + > + MaxLbaSize =3D 0; > + FvbInstance =3D mFvbModuleGlobal.FvbInstance; > + mFvbModuleGlobal.NumFv =3D 0; > + > + for (Idx =3D 0; ; Idx++) { > + if (mPlatformFvBaseAddress[Idx].FvSize =3D=3D 0 && mPlatformFvBase= Address[Idx].FvBase =3D=3D 0) { > + break; > + } > + BaseAddress =3D mPlatformFvBaseAddress[Idx].FvBase; > + FvHeader =3D (EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) BaseAddress; > + > + if (!IsFvHeaderValid (BaseAddress, FvHeader)) { > + DEBUG ((DEBUG_WARN, "ERROR - The FV in 0x%x is invalid!\n", FvHe= ader)); > + continue; > + } > + > + FvbInstance->Signature =3D FVB_INSTANCE_SIGNATURE; > + CopyMem (&(FvbInstance->FvHeader), FvHeader, FvHeader->HeaderLengt= h); > + > + FvHeader =3D &(FvbInstance->FvHeader); > + FvbInstance->FvBase =3D (UINTN)BaseAddress; > + > + // > + // Process the block map for each FV > + // > + FvbInstance->NumOfBlocks =3D 0; > + for (PtrBlockMapEntry =3D FvHeader->BlockMap; > + PtrBlockMapEntry->NumBlocks !=3D 0; > + PtrBlockMapEntry++) { > + // > + // Get the maximum size of a block. > + // > + if (MaxLbaSize < PtrBlockMapEntry->Length) { > + MaxLbaSize =3D PtrBlockMapEntry->Length; > + } > + FvbInstance->NumOfBlocks +=3D PtrBlockMapEntry->NumBlocks; > + } > + > + // > + // Add a FVB Protocol Instance > + // > + InstallFvbProtocol (FvbInstance); > + mFvbModuleGlobal.NumFv++; > + > + // > + // Move on to the next FvbInstance > + // > + FvbInstance =3D (EFI_FVB_INSTANCE *) ((UINTN)((UINT8 *)FvbInstance= ) + > + FvHeader->HeaderLength + > + (sizeof (EFI_FVB_INSTANCE) -= sizeof (EFI_FIRMWARE_VOLUME_HEADER))); > + > + } > + } > +} > diff --git a/Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/Sp= iFvbServiceStandaloneMm.c > b/Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbService= StandaloneMm.c > new file mode 100644 > index 000000000000..252c818d6551 > --- /dev/null > +++ b/Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbSer= viceStandaloneMm.c > @@ -0,0 +1,32 @@ > +/** @file > + MM driver source for several Serial Flash devices > + which are compliant with the Intel(R) Serial Flash Interface Compatibi= lity Specification. > + > + Copyright (c) Microsoft Corporation.
> + SPDX-License-Identifier: BSD-2-Clause-Patent > + > +**/ > + > +#include "SpiFvbServiceCommon.h" > +#include "SpiFvbServiceMm.h" > + > +/** > + The driver Standalone MM entry point. > + > + @param[in] ImageHandle Image handle of this driver. > + @param[in] MmSystemTable A pointer to the MM system table. > + > + @retval EFI_SUCCESS This function always returns EFI_SUCCE= SS. > + > +**/ > +EFI_STATUS > +EFIAPI > +SpiFvbStandaloneMmInitialize ( > + IN EFI_HANDLE ImageHandle, > + IN EFI_MM_SYSTEM_TABLE *MmSystemTable > + ) > +{ > + FvbInitialize (); > + > + return EFI_SUCCESS; > +} > diff --git a/Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/Sp= iFvbServiceTraditionalMm.c > b/Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbService= TraditionalMm.c > new file mode 100644 > index 000000000000..1c2dac70e3c6 > --- /dev/null > +++ b/Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbSer= viceTraditionalMm.c > @@ -0,0 +1,32 @@ > +/** @file > + MM driver source for several Serial Flash devices > + which are compliant with the Intel(R) Serial Flash Interface Compatibi= lity Specification. > + > + Copyright (c) Microsoft Corporation.
> + SPDX-License-Identifier: BSD-2-Clause-Patent > + > +**/ > + > +#include "SpiFvbServiceCommon.h" > +#include "SpiFvbServiceMm.h" > + > +/** > + The driver Traditional MM entry point. > + > + @param[in] ImageHandle Image handle of this driver. > + @param[in] SystemTable A pointer to the EFI system table. > + > + @retval EFI_SUCCESS This function always returns EFI_SUCCE= SS. > + > +**/ > +EFI_STATUS > +EFIAPI > +SpiFvbTraditionalMmInitialize ( > + IN EFI_HANDLE ImageHandle, > + IN EFI_SYSTEM_TABLE *SystemTable > + ) > +{ > + FvbInitialize (); > + > + return EFI_SUCCESS; > +} > diff --git a/Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/Sp= iFvbServiceCommon.h > b/Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbService= Common.h > new file mode 100644 > index 000000000000..e9d69e985814 > --- /dev/null > +++ b/Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbSer= viceCommon.h > @@ -0,0 +1,158 @@ > +/** @file > + Common source definitions used in serial flash drivers > + > +Copyright (c) 2017, Intel Corporation. All rights reserved.
> +SPDX-License-Identifier: BSD-2-Clause-Patent > + > +**/ > + > +#ifndef _SPI_FVB_SERVICE_COMMON_H > +#define _SPI_FVB_SERVICE_COMMON_H > + > +#include > +#include > +#include > +#include > +#include > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include > + > +// > +// Define two helper macro to extract the Capability field or Status fie= ld in FVB > +// bit fields > +// > +#define EFI_FVB2_CAPABILITIES (EFI_FVB2_READ_DISABLED_CAP | \ > + EFI_FVB2_READ_ENABLED_CAP | \ > + EFI_FVB2_WRITE_DISABLED_CAP | \ > + EFI_FVB2_WRITE_ENABLED_CAP | \ > + EFI_FVB2_LOCK_CAP \ > + ) > + > +#define EFI_FVB2_STATUS (EFI_FVB2_READ_STATUS | EFI_FVB2_WRITE_STATUS | = EFI_FVB2_LOCK_STATUS) > + > +#define FVB_INSTANCE_SIGNATURE SIGNATURE_32('F','V','B','I') > + > +typedef struct { > + UINT32 Signature; > + UINTN FvBase; > + UINTN NumOfBlocks; > + EFI_DEVICE_PATH_PROTOCOL *DevicePath; > + EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL FvbProtocol; > + EFI_FIRMWARE_VOLUME_HEADER FvHeader; > +} EFI_FVB_INSTANCE; > + > +typedef struct { > + EFI_FVB_INSTANCE *FvbInstance; > + UINT32 NumFv; > +} FVB_GLOBAL; > + > +// > +// Fvb Protocol instance data > +// > +#define FVB_INSTANCE_FROM_THIS(a) CR(a, EFI_FVB_INSTANCE, FvbProtocol, F= VB_INSTANCE_SIGNATURE) > + > +typedef struct { > + MEDIA_FW_VOL_DEVICE_PATH FvDevPath; > + EFI_DEVICE_PATH_PROTOCOL EndDevPath; > +} FV_PIWG_DEVICE_PATH; > + > +typedef struct { > + MEMMAP_DEVICE_PATH MemMapDevPath; > + EFI_DEVICE_PATH_PROTOCOL EndDevPath; > +} FV_MEMMAP_DEVICE_PATH; > + > +typedef struct { > + UINT32 FvBase; > + UINT32 FvSize; > +} FV_INFO; > + > +// > +// Protocol APIs > +// > +EFI_STATUS > +EFIAPI > +FvbProtocolGetAttributes ( > + IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, > + OUT EFI_FVB_ATTRIBUTES_2 *Attributes > + ); > + > +EFI_STATUS > +EFIAPI > +FvbProtocolSetAttributes ( > + IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, > + IN OUT EFI_FVB_ATTRIBUTES_2 *Attributes > + ); > + > +EFI_STATUS > +EFIAPI > +FvbProtocolGetPhysicalAddress ( > + IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, > + OUT EFI_PHYSICAL_ADDRESS *Address > + ); > + > +EFI_STATUS > +EFIAPI > +FvbProtocolGetBlockSize ( > + IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, > + IN EFI_LBA Lba, > + OUT UINTN *BlockSize, > + OUT UINTN *NumOfBlocks > + ); > + > +EFI_STATUS > +EFIAPI > +FvbProtocolRead ( > + IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, > + IN EFI_LBA Lba, > + IN UINTN Offset, > + IN OUT UINTN *NumBytes, > + OUT UINT8 *Buffer > + ); > + > +EFI_STATUS > +EFIAPI > +FvbProtocolWrite ( > + IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, > + IN EFI_LBA Lba, > + IN UINTN Offset, > + IN OUT UINTN *NumBytes, > + IN UINT8 *Buffer > + ); > + > +EFI_STATUS > +EFIAPI > +FvbProtocolEraseBlocks ( > + IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, > + ... > + ); > + > +BOOLEAN > +IsFvHeaderValid ( > + IN EFI_PHYSICAL_ADDRESS FvBase, > + IN CONST EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader > + ); > + > +EFI_STATUS > +GetFvbInfo ( > + IN EFI_PHYSICAL_ADDRESS FvBaseAddress, > + OUT EFI_FIRMWARE_VOLUME_HEADER **FvbInfo > + ); > + > +extern FVB_GLOBAL mFvbModuleGlobal; > +extern FV_MEMMAP_DEVICE_PATH mFvMemmapDevicePathTemplate; > +extern FV_PIWG_DEVICE_PATH mFvPIWGDevicePathTemplate; > +extern EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL mFvbProtocolTemplate; > +extern FV_INFO mPlatformFvBaseAddress[]; > +extern FV_INFO mPlatformDefaultBaseAddress[]; > + > +#endif > diff --git a/Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/Sp= iFvbServiceMm.h > b/Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbService= Mm.h > new file mode 100644 > index 000000000000..36af1130c8ee > --- /dev/null > +++ b/Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbSer= viceMm.h > @@ -0,0 +1,22 @@ > +/** @file > + Definitions common to MM implementation in this driver. > + > + Copyright (c) Microsoft Corporation.
> + SPDX-License-Identifier: BSD-2-Clause-Patent > + > +**/ > + > +#ifndef _SPI_FVB_SERVICE_MM_H_ > +#define _SPI_FVB_SERVICE_MM_H_ > + > +/** > + The function does the necessary initialization work for > + Firmware Volume Block Driver. > + > +**/ > +VOID > +FvbInitialize ( > + VOID > + ); > + > +#endif > diff --git a/Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/Sp= iFvbServiceSmm.inf > b/Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbService= Smm.inf > new file mode 100644 > index 000000000000..bf1306f00201 > --- /dev/null > +++ b/Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbSer= viceSmm.inf > @@ -0,0 +1,68 @@ > +### @file > +# Component description file for the Serial Flash device Runtime driver. > +# > +# Copyright (c) 2017-2019, Intel Corporation. All rights reserved.
> +# Copyright (c) Microsoft Corporation.
> +# > +# SPDX-License-Identifier: BSD-2-Clause-Patent > +# > +### > + > +[Defines] > + INF_VERSION =3D 0x00010017 > + BASE_NAME =3D SpiFvbServiceSmm > + FILE_GUID =3D 68A10D85-6858-4402-B070-028B3EA2174= 7 > + VERSION_STRING =3D 1.0 > + MODULE_TYPE =3D DXE_SMM_DRIVER > + PI_SPECIFICATION_VERSION =3D 1.10 > + ENTRY_POINT =3D SpiFvbTraditionalMmInitialize > + > +# > +# The following information is for reference only and not required by th= e build tools. > +# > +# VALID_ARCHITECTURES =3D IA32 X64 > +# > + > +[LibraryClasses] > + PcdLib > + MemoryAllocationLib > + CacheMaintenanceLib > + BaseMemoryLib > + DebugLib > + BaseLib > + UefiBootServicesTableLib > + UefiDriverEntryPoint > + SpiFlashCommonLib > + MmServicesTableLib > + > +[Packages] > + MdePkg/MdePkg.dec > + MdeModulePkg/MdeModulePkg.dec > + IntelSiliconPkg/IntelSiliconPkg.dec > + > +[Pcd] > + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase ## CONS= UMES > + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize ## CONS= UMES > + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize ## CONS= UMES > + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize ## CONS= UMES > + gIntelSiliconPkgTokenSpaceGuid.PcdFlashMicrocodeFvBase ## CONS= UMES > + gIntelSiliconPkgTokenSpaceGuid.PcdFlashMicrocodeFvSize ## CONS= UMES > + > +[Sources] > + FvbInfo.c > + SpiFvbServiceCommon.h > + SpiFvbServiceCommon.c > + SpiFvbServiceMm.h > + SpiFvbServiceMm.c > + SpiFvbServiceTraditionalMm.c > + > +[Protocols] > + gEfiDevicePathProtocolGuid ## PRODUCES > + gEfiSmmFirmwareVolumeBlockProtocolGuid ## PRODUCES > + > +[Guids] > + gEfiFirmwareFileSystem2Guid ## CONSUMES > + gEfiSystemNvDataFvGuid ## CONSUMES > + > +[Depex] > + TRUE > diff --git a/Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/Sp= iFvbServiceStandaloneMm.inf > b/Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbService= StandaloneMm.inf > new file mode 100644 > index 000000000000..b66233968247 > --- /dev/null > +++ b/Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbSer= viceStandaloneMm.inf > @@ -0,0 +1,67 @@ > +### @file > +# Component description file for the Serial Flash device Standalone MM d= river. > +# > +# Copyright (c) 2017-2019, Intel Corporation. All rights reserved.
> +# Copyright (c) Microsoft Corporation.
> +# > +# SPDX-License-Identifier: BSD-2-Clause-Patent > +# > +### > + > +[Defines] > + INF_VERSION =3D 0x0001001B > + BASE_NAME =3D SpiFvbServiceStandaloneMm > + FILE_GUID =3D E6313655-8BD0-4EAB-B319-AD5E212CE6A= B > + VERSION_STRING =3D 1.0 > + MODULE_TYPE =3D MM_STANDALONE > + PI_SPECIFICATION_VERSION =3D 0x00010032 > + ENTRY_POINT =3D SpiFvbStandaloneMmInitialize > + > +# > +# The following information is for reference only and not required by th= e build tools. > +# > +# VALID_ARCHITECTURES =3D IA32 X64 > +# > + > +[LibraryClasses] > + BaseLib > + BaseMemoryLib > + CacheMaintenanceLib > + DebugLib > + MemoryAllocationLib > + PcdLib > + MmServicesTableLib > + SpiFlashCommonLib > + StandaloneMmDriverEntryPoint > + > +[Packages] > + MdePkg/MdePkg.dec > + MdeModulePkg/MdeModulePkg.dec > + IntelSiliconPkg/IntelSiliconPkg.dec > + > +[Pcd] > + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase ## CONS= UMES > + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize ## CONS= UMES > + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize ## CONS= UMES > + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize ## CONS= UMES > + gIntelSiliconPkgTokenSpaceGuid.PcdFlashMicrocodeFvBase ## CONS= UMES > + gIntelSiliconPkgTokenSpaceGuid.PcdFlashMicrocodeFvSize ## CONS= UMES > + > +[Sources] > + FvbInfo.c > + SpiFvbServiceCommon.h > + SpiFvbServiceCommon.c > + SpiFvbServiceMm.h > + SpiFvbServiceMm.c > + SpiFvbServiceStandaloneMm.c > + > +[Protocols] > + gEfiDevicePathProtocolGuid ## PRODUCES > + gEfiSmmFirmwareVolumeBlockProtocolGuid ## PRODUCES > + > +[Guids] > + gEfiFirmwareFileSystem2Guid ## CONSUMES > + gEfiSystemNvDataFvGuid ## CONSUMES > + > +[Depex] > + TRUE > diff --git a/Silicon/Intel/IntelSiliconPkg/IntelSiliconPkg.dsc b/Silicon/= Intel/IntelSiliconPkg/IntelSiliconPkg.dsc > index 7eb9c9def60a..7e446c97a5fb 100644 > --- a/Silicon/Intel/IntelSiliconPkg/IntelSiliconPkg.dsc > +++ b/Silicon/Intel/IntelSiliconPkg/IntelSiliconPkg.dsc > @@ -40,6 +40,9 @@ [LibraryClasses] > PeiGetVtdPmrAlignmentLib|IntelSiliconPkg/Library/PeiGetVtdPmrAlignment= Lib/PeiGetVtdPmrAlignmentLib.inf > TpmMeasurementLib|MdeModulePkg/Library/TpmMeasurementLibNull/TpmMeasur= ementLibNull.inf > MicrocodeLib|UefiCpuPkg/Library/MicrocodeLib/MicrocodeLib.inf > + SpiFlashCommonLib|IntelSiliconPkg/Library/SpiFlashCommonLibNull/SpiFla= shCommonLibNull.inf > + UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiB= ootServicesTableLib.inf > + UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEnt= ryPoint.inf >=20 > [LibraryClasses.common.PEIM] > PeimEntryPoint|MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf > @@ -61,8 +64,14 @@ [LibraryClasses.common.DXE_DRIVER] >=20 > [LibraryClasses.common.DXE_SMM_DRIVER] > MemoryAllocationLib|MdePkg/Library/SmmMemoryAllocationLib/SmmMemoryAll= ocationLib.inf > + MmServicesTableLib|MdePkg/Library/MmServicesTableLib/MmServicesTableLi= b.inf > SmmServicesTableLib|MdePkg/Library/SmmServicesTableLib/SmmServicesTabl= eLib.inf >=20 > +[LibraryClasses.common.MM_STANDALONE] > + > MemoryAllocationLib|StandaloneMmPkg/Library/StandaloneMmMemoryAllocationL= ib/StandaloneMmMemoryAllocationLib.inf > + MmServicesTableLib|MdePkg/Library/StandaloneMmServicesTableLib/Standal= oneMmServicesTableLib.inf > + StandaloneMmDriverEntryPoint|MdePkg/Library/StandaloneMmDriverEntryPoi= nt/StandaloneMmDriverEntryPoint.inf > + > ########################################################################= ########################### > # > # Components Section - list of the modules and components that will be p= rocessed by compilation > @@ -86,6 +95,8 @@ [Components] > IntelSiliconPkg/Library/DxeSmbiosDataHobLib/DxeSmbiosDataHobLib.inf > IntelSiliconPkg/Feature/PcieSecurity/IntelPciDeviceSecurityDxe/IntelPc= iDeviceSecurityDxe.inf > IntelSiliconPkg/Feature/PcieSecurity/SamplePlatformDevicePolicyDxe/Sam= plePlatformDevicePolicyDxe.inf > + IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbServiceSmm.inf > + IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbServiceStandaloneMm.= inf > IntelSiliconPkg/Feature/VTd/IntelVTdDxe/IntelVTdDxe.inf > IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/IntelVTdDmarPei.inf > IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/IntelVTdPmrPei.inf > -- > 2.28.0.windows.1