From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mga04.intel.com (mga04.intel.com [192.55.52.120]) by mx.groups.io with SMTP id smtpd.web11.5183.1618887617202939550 for ; Mon, 19 Apr 2021 20:00:17 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@intel.onmicrosoft.com header.s=selector2-intel-onmicrosoft-com header.b=PIjG64E6; spf=pass (domain: intel.com, ip: 192.55.52.120, mailfrom: guo.dong@intel.com) IronPort-SDR: OI8s0vBT+TqTOvTh8DTXuluJ0ZutOHgF2bEoGmz+NrVLXW72cfwX8pmxNnPfDqwscz3+KJLqYL UeWMOx2RRYag== X-IronPort-AV: E=McAfee;i="6200,9189,9959"; a="193309058" X-IronPort-AV: E=Sophos;i="5.82,235,1613462400"; d="scan'208";a="193309058" Received: from orsmga006.jf.intel.com ([10.7.209.51]) by fmsmga104.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 19 Apr 2021 20:00:14 -0700 IronPort-SDR: DEwz5Erm5Ex34PyeArOIBk3z+sMEphuAHouud6B/Br9K8NiSc3i0NgtJXZvTgusZHsR7CWy7z4 iszm/JAGajdQ== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.82,235,1613462400"; d="scan'208";a="385168594" Received: from fmsmsx602.amr.corp.intel.com ([10.18.126.82]) by orsmga006.jf.intel.com with ESMTP; 19 Apr 2021 20:00:13 -0700 Received: from fmsmsx608.amr.corp.intel.com (10.18.126.88) by fmsmsx602.amr.corp.intel.com (10.18.126.82) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2106.2; Mon, 19 Apr 2021 20:00:13 -0700 Received: from fmsmsx609.amr.corp.intel.com (10.18.126.89) by fmsmsx608.amr.corp.intel.com (10.18.126.88) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2106.2; Mon, 19 Apr 2021 20:00:13 -0700 Received: from FMSEDG603.ED.cps.intel.com (10.1.192.133) by fmsmsx609.amr.corp.intel.com (10.18.126.89) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2106.2 via Frontend Transport; Mon, 19 Apr 2021 20:00:13 -0700 Received: from NAM10-MW2-obe.outbound.protection.outlook.com (104.47.55.104) by edgegateway.intel.com (192.55.55.68) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.1.2106.2; Mon, 19 Apr 2021 20:00:12 -0700 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=UuN7/66NWbFNeihdLdtESsTqwkS1vx5diJiKDczOLZqr6A5ccTo+R4xt8SihFojynV+p4J5BHVasEh6ZH7F14RQDkO/ykZ4SzBJtrJCwwTU/ksiwU+qDVHDFxnJKlGS8wbusoBbZLex46r3A2NUzB/6amNU9FW1xQfuU+q2FFa4h+nas+PHMQNGlqkcHCL9d9MlZ1WCYF/LqpH2axlshoH/E2G6L1tiXvpzr08HGqpJ89m0iisfliDQ+QP5rHJvXYM5j/t6tOr+a+HxdDcFG1QGFqKBwC8hRlXUzSqvDPhse5KX/UcQ4GmPfR1gvmaJ1flKVgAx47e8W7qybaRk6qw== 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=1S7Gousm/JomABCldPgJajbU0viTPzmagqaST+7Eil0=; b=Whoq0xShpAVyexQvy1on2nPYiO86BE+0mMpEd3g47EJ+McVyNnjEv2Z1onlM8HmlNI0uDfSpfPlHLaOkYABw1fLBb/Z4bDNeLOKGujW+mcpjJF9MkODwtfxW6VUbNutNHXoxsHbzIcpfpbekQMHDbThJDlNwMoP0VsCUPMnu/pbugLvm/L+pXmvcC+Q7Nldxm4pER35eslPPCqd3qDKZwvy4zW8ccIRQkQVK7fB4Y0xne/4NtSeZvX7d5ieRYoHhTUnmody2qSEkMDUyPDE4Esnb0J/4wVPTlG/1pUPsKIQzVrc0/NoI8MM/l24RWakzAxK+/Pr2SwP55caPJSfVTw== 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=1S7Gousm/JomABCldPgJajbU0viTPzmagqaST+7Eil0=; b=PIjG64E65CoWjpye3q+EVEPPtjS36rE5f4TMlcsvcxUBb8H5ohj0lL9qZUE9TelMWK04sI79Qug74nxqbzLfSCYQxHcoG5WizGHQxdUbylpGQaHMGIaEiB0uvSmpa6oFtQtLP0NhQMWwOivmJFB2YRPDR90I6cUZCXrwXibVS+E= Received: from BYAPR11MB3622.namprd11.prod.outlook.com (2603:10b6:a03:fe::30) by BY5PR11MB4007.namprd11.prod.outlook.com (2603:10b6:a03:189::28) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4042.16; Tue, 20 Apr 2021 03:00:11 +0000 Received: from BYAPR11MB3622.namprd11.prod.outlook.com ([fe80::49f0:3ec3:7ce5:60db]) by BYAPR11MB3622.namprd11.prod.outlook.com ([fe80::49f0:3ec3:7ce5:60db%7]) with mapi id 15.20.4042.024; Tue, 20 Apr 2021 03:00:11 +0000 From: "Guo Dong" To: "Ni, Ray" , "mikuback@linux.microsoft.com" , "devel@edk2.groups.io" 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: AQHXMrIXseJOfmEQJ0uf8ZO+2RCexqq8ug2Q Date: Tue, 20 Apr 2021 03:00:10 +0000 Message-ID: References: <20210416023152.771-1-mikuback@linux.microsoft.com> <20210416023152.771-11-mikuback@linux.microsoft.com> In-Reply-To: Accept-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: dlp-product: dlpe-windows dlp-reaction: no-action dlp-version: 11.5.1.3 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: [68.2.51.172] x-ms-publictraffictype: Email x-ms-office365-filtering-correlation-id: 9acceb7e-33ce-484e-3787-08d903a86990 x-ms-traffictypediagnostic: BY5PR11MB4007: x-ms-exchange-transport-forked: True x-microsoft-antispam-prvs: x-ms-oob-tlc-oobclassifiers: OLM:10000; x-ms-exchange-senderadcheck: 1 x-microsoft-antispam: BCL:0; x-microsoft-antispam-message-info: TxIPwuH7+exQM+h8opgmgZqajoM0DtPIwM6hxmxxLOv81Gu54i5QjtAztREC0Oge0FU9sbX3uTKqdQrC8Q4VjPbAt8MEUE5E6/Z/BbqTve6T4YOeY6dZt6rYWL2/UqGXeXvMekAr254oy/7bnx8wk66JgsoFlK7Uldt7s3OcHfC6xi86/Y+hqXnxX5+g7WSDCYB4VqqzaSItiiUL18slHdH7eSt832KP7hO5WM6jRzF3OjD3W8N9dNVjwJwqdD5JgM5MqbL3zCcQresdjMgFdyO+SvuPuLf9E7cwHUhWuk8m6HsrjP5zryAo/bO6UPCB9w+AbTdP+1OMuAs1XI0VlDra1324CY85Hh1rdv7aGoZAI8y+zeMDDkq78hqBmMaXiTXmTeUsXSZVGXDQnYkTrNbnnVBV7u6wfbbPqSGUGe7ZR9ermE9GdDdxJFohtssZPuJJKTFO+0y+2inYnztms0ubYZxN6daPH9UmqmvpWLhV7WFaT7WAd4B1GMeDeLy/C0aBtUHxCmoopHVqvuaQzFjfQjzDTg/fTh47clyd9yCZca1p7lX21u2bo6hreFTALPXoiYIb+1UdP6bUwFW0M2ya1u+x+uzO8GGsdmXNa9/RR6GtsRlPHg2c5dmIK2va3Okm/m68dRNH/x53aIIbY9NTbqg+qNREXOtLmO3eEF9cxlrDMpVeYy2rZMP8WlWU x-forefront-antispam-report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:BYAPR11MB3622.namprd11.prod.outlook.com;PTR:;CAT:NONE;SFS:(366004)(346002)(396003)(376002)(136003)(39860400002)(6506007)(186003)(4326008)(7696005)(66946007)(66446008)(8936002)(64756008)(19627235002)(478600001)(38100700002)(26005)(66476007)(76116006)(316002)(30864003)(122000001)(53546011)(66556008)(33656002)(52536014)(9686003)(45080400002)(110136005)(55016002)(71200400001)(86362001)(83380400001)(107886003)(2906002)(5660300002)(8676002)(579004)(559001);DIR:OUT;SFP:1102; x-ms-exchange-antispam-messagedata: =?us-ascii?Q?j/EAsC5mNuXxBvT6skZV+F92LhGPUEKtGPQt9oo6/aEQTwdJQGLtxFU7NsiY?= =?us-ascii?Q?iuBvZJvkRGMbmgOCFeaiTA03xzbSZYlneYqtgHy1g+td0aCH4qdDUHxjcrFT?= =?us-ascii?Q?HNjwuH0T9lmHTTgjgzByEAq/nxeqWfsBUKtfIGiOPTkXxkun3/dQFLLJY2Cc?= =?us-ascii?Q?aMON4MZIk/WYItn3/gCr4SaXBQcCR3zsCfxy66jdMo2J2bu8UerF5phd0BhP?= =?us-ascii?Q?ig2dofFS490nAnOXLms0bg5I14YVvcLjlqE1MJMgZJgTIs8yG9bcNN4tNTVZ?= =?us-ascii?Q?9ECBb3vFZHh2QT6Nv+cbDabGPupMdYT93ihRU53b4w/TfKBgekyb/ml3xpgv?= =?us-ascii?Q?ScPkgZYQBtNPR19852lmtH0NMc/NNysytCWTScleRrGtyWGWSSObpPLMfqOk?= =?us-ascii?Q?srDgFBKKAZU5iEashLXXUeaxrNBzC4UlaxbLO1ehuGIxXWkQTS4lp8uQ9xwe?= =?us-ascii?Q?i21A/Nnr+a6a1J0dW09OPStRdcX8zBplOs2cqqozIkDz5XvADc8Gt+qQSPbd?= =?us-ascii?Q?w0Bga2wCJxYN89j+vOFgs7nmqv0Knk8uvCUfM6M/eNK/MXb1RX1k79HODqn4?= =?us-ascii?Q?3ktyDWoD1EEmdZJmomNjK+NCDXl2UM2ccZhIecJ8e0pjMTJ7UX29jb17UA2E?= =?us-ascii?Q?QRDE3CxPPsY3VunvHMEGFg8x39/dx1DVj9/+7+IDQapVXo1ovZW2RwxmG6b7?= =?us-ascii?Q?vLrK4cja9ztN+R0Jse2VopD+ldbHpeWKKCQXkA1ShQkpoUpAOoDZKkSRvqII?= =?us-ascii?Q?WL8cCO/c7TtkuOvua9AAbatlp7T0nlHlI3mtRPqTeGfiShRSs+6A5JxhqR5I?= =?us-ascii?Q?HOeIoeQ/6a5hRhb1D8bFsc/yAW+RDr9RELW4mlsdzJUpm1WT2nZcHVCPT6s0?= =?us-ascii?Q?5InOme6wRgsvMFH1fe4LG4LPgv2gaLlwfoe42AWomFc/v37V3LB8vqCan9Q3?= =?us-ascii?Q?sbGJwa/L8Crkm7f/wx7rMGegjw9bgWXkI3j2QkaDX2GID0AxfZQGaec80TvS?= =?us-ascii?Q?TLrg8AGdd7umEu1mWJks8N3031NI9El6BfujbJc7Rv4safl/LQmHsyIB4aWm?= =?us-ascii?Q?ToyRtIWiMiJPwtXcxWbFeF778nHpTHB63yCYyoIp5l4xZ//iWYnA2A1BG+HX?= =?us-ascii?Q?azQAugBPy7kw3XaWECSLUTLbi0U5iVfWE+ibe4P+Hnotkr9Yk/6qqL0HPI79?= =?us-ascii?Q?4Z/sT4lhPxYvh2qYf2PpKKuW2Qm7yiwcN1/CrHU8TaaNAzemAV8vAHcsiVxi?= =?us-ascii?Q?5e5sfvPecOdUWje5Ti4i7VQtNa5FXyELTT9XG3FR9odQH2/RNddJvH5lbREY?= =?us-ascii?Q?Tbo=3D?= MIME-Version: 1.0 X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-AuthSource: BYAPR11MB3622.namprd11.prod.outlook.com X-MS-Exchange-CrossTenant-Network-Message-Id: 9acceb7e-33ce-484e-3787-08d903a86990 X-MS-Exchange-CrossTenant-originalarrivaltime: 20 Apr 2021 03:00:10.8424 (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: 4Tze+ym204UkCoSxnUA//mAf4zEl6U+W4DHSzQObtJib4+ONIMD/wYuCDqFfEqpuyprrOfDluDKaoLdwjliCBA== X-MS-Exchange-Transport-CrossTenantHeadersStamped: BY5PR11MB4007 Return-Path: guo.dong@intel.com X-OriginatorOrg: intel.com Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Hi Ray, This patch is about FVB module change. It is not related with SPI since it = depends on SPI library. The SPI hardware sequence could be used in SPI library. I reviewed this patch, I think it is OK to replace the one used in existing= platform FVB driver. Thanks, Guo > -----Original Message----- > From: Ni, Ray > Sent: Friday, April 16, 2021 4:18 AM > 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 >=20 > Guo, > I remember you mentioned to me there is a standard way to manipulate the > flash storage because there is a HW between the SW and the real flash tha= t > does 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? >=20 > Michael, > Having a universal implementation for SPI access is wonderful! Can you > please share the documentation that explain the Intel Serial Flash Interf= ace > Compatibility spec? >=20 > > -----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 > > > > From: Michael Kubacki > > > > REF:https://bugzilla.tianocore.org/show_bug.cgi?id=3D3307 > > > > 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. > > > > 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/SpiFvbServiceCo= m > mon.c | 903 ++++++++++++++++++++ > > > Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbServiceMm= . > c | 271 ++++++ > > > Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbServiceSt= an > daloneMm.c | 32 + > > > Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbServiceTr= adi > tionalMm.c | 32 + > > > Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbServiceCo= m > mon.h | 158 ++++ > > > Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbServiceMm= . > h | 22 + > > > Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbServiceSm= m > .inf | 68 ++ > > > Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbServiceSt= an > daloneMm.inf | 67 ++ > > Silicon/Intel/IntelSiliconPkg/IntelSiliconPkg.dsc = | 11 + > > 10 files changed, 1658 insertions(+) > > > > diff --git > a/Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/FvbInfo.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(PcdFlashNvStorageVariableBase) > > +#define SYSTEM_NV_BLOCK_NUM > ((FixedPcdGet32(PcdFlashNvStorageVariableSize)+ > > FixedPcdGet32(PcdFlashNvStorageFtwWorkingSize) + > FixedPcdGet32(PcdFlashNvStorageFtwSpareSize))/ > > 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, = which > 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 > details on EFI_FVB_ATTRIBUTES_2 > > + sizeof (EFI_FIRMWARE_VOLUME_HEADER) + sizeof > (EFI_FV_BLOCK_MAP_ENTRY), > > + 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)- > >HeaderLength)); > > + DEBUG ((DEBUG_INFO, "Header Checksum: 0x%X\n", (*FvbInfo)- > >Checksum)); > > + DEBUG ((DEBUG_INFO, "FvBlockMap[0].NumBlocks: 0x%x \n", > (*FvbInfo)->BlockMap[0].NumBlocks)); > > + DEBUG ((DEBUG_INFO, "FvBlockMap[0].BlockLength: 0x%x \n", > (*FvbInfo)->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", > (*FvbInfo)->BlockMap[1].Length)); > > + > > + return EFI_SUCCESS; > > + } > > + } > > + return EFI_NOT_FOUND; > > +} > > diff --git > a/Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbService= Co > mmon.c > > > b/Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbService= Co > mmon.c > > new file mode 100644 > > index 000000000000..dab818e98087 > > --- /dev/null > > +++ > b/Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbService= Co > mmon.c > > @@ -0,0 +1,903 @@ > > +/** @file > > + Common driver source for several Serial Flash devices > > + which are compliant with the Intel(R) Serial Flash Interface Compati= bility > 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 > performance issue. > > +// > > +FV_INFO mPlatformFvBaseAddress[] =3D { > > + {0, 0}, // {FixedPcdGet32(PcdFlashNvStorageVariableBase), > FixedPcdGet32(PcdFlashNvStorageVariableSize)}, > > + {0, 0}, // {FixedPcdGet32(PcdFlashMicrocodeFvBase), > FixedPcdGet32(PcdFlashMicrocodeFvSize)}, > > + {0, 0} > > +}; > > + > > +FV_INFO mPlatformDefaultBaseAddress[] =3D { > > + {0, 0}, // {FixedPcdGet32(PcdFlashNvStorageVariableBase), > FixedPcdGet32(PcdFlashNvStorageVariableSize)}, > > + {0, 0}, // {FixedPcdGet32(PcdFlashMicrocodeFvBase), > FixedPcdGet32(PcdFlashMicrocodeFvSize)}, > > + {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 startin= g > address > > + of the Lba > > + @param[out] LbaLength On output, contains the length of the bl= ock > > + @param[out] NumOfBlocks A pointer to a caller allocated UINTN in > which the > > + number of consecutive blocks starting wi= th 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 belo= ngs > 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), BlockLen= gth); > > + 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 blo= ck. > > + > > + @param[in] FvbInstance The pointer to the EFI_FVB_INS= TANCE > > + @param[in] Lba The logical block address to b= e read from > > + @param[in] BlockOffset Offset into the block at which= to begin > reading > > + @param[in] NumBytes Pointer that on input contains= the total > size of > > + the buffer. On output, it cont= ains the total number > > + of bytes read > > + @param[in] Buffer Pointer to a caller allocated = buffer that will > be > > + used to hold the data read > > + > > + > > + @retval EFI_SUCCESS The firmware volume was read > successfully and > > + contents are in Buffer > > + @retval EFI_BAD_BUFFER_SIZE Read attempted across a LBA > boundary. On output, > > + NumBytes contains the total nu= mber of bytes > returned > > + in Buffer > > + @retval EFI_ACCESS_DENIED The firmware volume is in the > ReadDisabled state > > + @retval EFI_DEVICE_ERROR The block device is not functi= oning > correctly and > > + could not be read > > + @retval EFI_INVALID_PARAMETER Instance not found, or NumByte= s, > 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 *)NumByte= s, > 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_INSTANC= E > > + @param[in] Lba The starting logical block index t= o write to > > + @param[in] BlockOffset Offset into the block at which to = begin > writing > > + @param[in] NumBytes Pointer that on input contains the= total > size of > > + the buffer. On output, it contains= the total number > > + of bytes actually written > > + @param[in] Buffer Pointer to a caller allocated buff= er that > contains > > + the source for the write > > + @retval EFI_SUCCESS The firmware volume was written > successfully > > + @retval EFI_BAD_BUFFER_SIZE Write attempted across a LBA > boundary. On output, > > + NumBytes contains the total number= of bytes > > + actually written > > + @retval EFI_ACCESS_DENIED The firmware volume is in the > WriteDisabled state > > + @retval EFI_DEVICE_ERROR The block device is not functionin= g > correctly and > > + could not be written > > + @retval EFI_INVALID_PARAMETER Instance not found, or NumBytes, > Buffer 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 *)NumByt= es, > 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 > completed > > + @retval EFI_ACCESS_DENIED The firmware volume is in the > WriteDisabled state > > + @retval EFI_DEVICE_ERROR The block device is not functioning > correctly and > > + could not be written. Firmware devic= e 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 th= e > > + input parameter, and returns the new setting of the volume > > + > > + @param[in] FvbInstance The pointer to the EFI_FVB_INSTANC= E. > > + @param[in] Attributes On input, it is a pointer to > EFI_FVB_ATTRIBUTES_2 > > + containing the desired firmware vo= lume settings. > > + On successful return, it contains = the new settings > > + of the firmware volume > > + > > + @retval EFI_SUCCESS Successfully returns > > + @retval EFI_ACCESS_DENIED The volume setting is locked and > cannot be modified > > + @retval EFI_INVALID_PARAMETER Instance not found, or The > attributes 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.Attributes); > > + 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 & > UnchangedAttributes)) { > > + 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, > &gEfiFirmwareFileSystem2Guid, 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 whi= ch > > + the size of the block is returned > > + @param[out] NumOfBlocks A pointer to a caller allocated UINTN in whi= ch > the > > + number of consecutive blocks starting with L= ba is > > + returned. All blocks in this range have a si= ze 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 th= e > > + variable argument list. The entire parameter list of blocks must be > verified > > + prior to erasing any blocks. If a block is requested that does not = exist > > + within the associated firmware volume (it has a larger index than th= e last > > + block of the firmware volume), the EraseBlock() function must return > > + EFI_INVALID_PARAMETER without modifying the contents of the > firmware volume. > > + > > + @param[in] This Calling context > > + @param[in] ... Starting LBA followed by Number of Lba to er= ase. > > + a -1 to terminate the list. > > + > > + @retval EFI_SUCCESS The erase request was successfully complet= ed > > + @retval EFI_ACCESS_DENIED The firmware volume is in the > WriteDisabled state > > + @retval EFI_DEVICE_ERROR The block device is not functioning correc= tly > and > > + could not be written. Firmware device may = have 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 ei= ther > > + 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 wil= l > > + attempt to write only the specified bytes. If the writes do not stic= k, > > + 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 writ= e > > + @param[in,out] NumBytes On input, indicates the requested write si= ze. > On > > + output, indicates the actual number of byt= es written > > + @param[in] Buffer Buffer containing source data for the writ= e. > > + > > + @retval EFI_SUCCESS The firmware volume was written succes= sfully > > + @retval EFI_BAD_BUFFER_SIZE Write attempted across a LBA boundary. > On output, > > + NumBytes contains the total number of = bytes > > + actually written > > + @retval EFI_ACCESS_DENIED The firmware volume is in the > WriteDisabled state > > + @retval EFI_DEVICE_ERROR The block device is not functioning > correctly 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: > 0x%x\n", > > + Lba, > > + Offset, > > + *NumBytes, > > + Buffer) > > + ); > > + > > + return FvbWriteBlock (FvbInstance, Lba, Offset, NumBytes, Buffer); > > +} > > + > > +/** > > + Reads data beginning at Lba:Offset from FV. The Read terminates eith= er > > + 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 wil= l > > + attempt to write only the specified bytes. If the writes do not stic= k, > > + 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 writ= e > > + @param[in,out] NumBytes On input, indicates the requested write si= ze. > On > > + output, indicates the actual number of byt= es written > > + @param[in] Buffer Buffer containing source data for the writ= e. > > + > > + @retval EFI_SUCCESS The firmware volume was read successfu= lly > and > > + contents are in Buffer > > + @retval EFI_BAD_BUFFER_SIZE Read attempted across a LBA boundary. > On output, > > + NumBytes contains the total number of = bytes returned > > + in Buffer > > + @retval EFI_ACCESS_DENIED The firmware volume is in the > ReadDisabled state > > + @retval EFI_DEVICE_ERROR The block device is not functioning > correctly 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/SpiFvbService= M > m.c > > > b/Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbService= M > m.c > > new file mode 100644 > > index 000000000000..42a0828c6fae > > --- /dev/null > > +++ > b/Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbService= M > m.c > > @@ -0,0 +1,271 @@ > > +/** @file > > + MM driver source for several Serial Flash devices > > + which are compliant with the Intel(R) Serial Flash Interface Compati= bility > 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 struct= ure, > > + which contains the information about one F= V. > > + > > + @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 *) > AllocateRuntimeCopyPool (sizeof > > (FV_MEMMAP_DEVICE_PATH), &mFvMemmapDevicePathTemplate); > > + if (FvbInstance->DevicePath =3D=3D NULL) { > > + DEBUG ((DEBUG_INFO, "SpiFvbServiceSmm.c: Memory allocation for > MEMMAP_DEVICE_PATH failed\n")); > > + return; > > + } > > + ((FV_MEMMAP_DEVICE_PATH *) FvbInstance->DevicePath)- > >MemMapDevPath.StartingAddress =3D FvbInstance->FvBase; > > + ((FV_MEMMAP_DEVICE_PATH *) FvbInstance->DevicePath)- > >MemMapDevPath.EndingAddress =3D FvbInstance->FvBase + > > FvHeader->FvLength - 1; > > + } else { > > + FvbInstance->DevicePath =3D (EFI_DEVICE_PATH_PROTOCOL *) > AllocateRuntimeCopyPool (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.FvName, > > + (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(PcdFlashNvStorageVariableBase); > > + mPlatformFvBaseAddress[0].FvSize =3D > PcdGet32(PcdFlashNvStorageVariableSize); > > + mPlatformFvBaseAddress[1].FvBase =3D > PcdGet32(PcdFlashMicrocodeFvBase); > > + mPlatformFvBaseAddress[1].FvSize =3D > PcdGet32(PcdFlashMicrocodeFvSize); > > + mPlatformDefaultBaseAddress[0].FvBase =3D > PcdGet32(PcdFlashNvStorageVariableBase); > > + mPlatformDefaultBaseAddress[0].FvSize =3D > PcdGet32(PcdFlashNvStorageVariableSize); > > + mPlatformDefaultBaseAddress[1].FvBase =3D > PcdGet32(PcdFlashMicrocodeFvBase); > > + mPlatformDefaultBaseAddress[1].FvSize =3D > PcdGet32(PcdFlashMicrocodeFvSize); > > + > > + // > > + // 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 && > mPlatformFvBaseAddress[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", > FvHeader)); > > + 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 > data\n", BaseAddress)); > > + // > > + // Spi erase > > + // > > + BytesErased =3D (UINTN) FvHeader->BlockMap->Length; > > + Status =3D SpiFlashBlockErase( (UINTN) BaseAddress, &BytesEras= ed); > > + 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- > >BlockMap->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, > (UINT8*)FvHeader); > > + if (EFI_ERROR (Status)) { > > + DEBUG ((DEBUG_WARN, "ERROR - SpiFlashWrite Error %r\n", > Status)); > > + 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", Stat= us)); > > + continue; > > + } > > + DEBUG ((DEBUG_INFO, "FV Header @ 0x%X restored with static > data\n", BaseAddress)); > > + // > > + // Clear cache for this range. > > + // > > + WriteBackInvalidateDataCacheRange ( (VOID *) (UINTN) BaseAddre= ss, > FvHeader->BlockMap->Length); > > + } > > + } > > + > > + // > > + // Calculate the total size for all firmware volume block instance= s > > + // > > + BufferSize =3D 0; > > + for (Idx =3D 0; ; Idx++) { > > + if (mPlatformFvBaseAddress[Idx].FvSize =3D=3D 0 && > mPlatformFvBaseAddress[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", > FvHeader)); > > + continue; > > + } > > + > > + BufferSize +=3D (FvHeader->HeaderLength + > > + sizeof (EFI_FVB_INSTANCE) - > > + sizeof (EFI_FIRMWARE_VOLUME_HEADER) > > + ); > > + } > > + > > + mFvbModuleGlobal.FvbInstance =3D (EFI_FVB_INSTANCE *) > AllocateRuntimeZeroPool (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 && > mPlatformFvBaseAddress[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", > FvHeader)); > > + continue; > > + } > > + > > + FvbInstance->Signature =3D FVB_INSTANCE_SIGNATURE; > > + CopyMem (&(FvbInstance->FvHeader), FvHeader, FvHeader- > >HeaderLength); > > + > > + 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 *)FvbInstan= ce) > + > > + FvHeader->HeaderLength + > > + (sizeof (EFI_FVB_INSTANCE)= - sizeof > (EFI_FIRMWARE_VOLUME_HEADER))); > > + > > + } > > + } > > +} > > diff --git > a/Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbService= Sta > ndaloneMm.c > > > b/Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbService= Sta > ndaloneMm.c > > new file mode 100644 > > index 000000000000..252c818d6551 > > --- /dev/null > > +++ > b/Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbService= Sta > ndaloneMm.c > > @@ -0,0 +1,32 @@ > > +/** @file > > + MM driver source for several Serial Flash devices > > + which are compliant with the Intel(R) Serial Flash Interface Compati= bility > 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_SUC= CESS. > > + > > +**/ > > +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/SpiFvbService= Tra > ditionalMm.c > > > b/Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbService= Tra > ditionalMm.c > > new file mode 100644 > > index 000000000000..1c2dac70e3c6 > > --- /dev/null > > +++ > b/Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbService= Tra > ditionalMm.c > > @@ -0,0 +1,32 @@ > > +/** @file > > + MM driver source for several Serial Flash devices > > + which are compliant with the Intel(R) Serial Flash Interface Compati= bility > 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_SUC= CESS. > > + > > +**/ > > +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/SpiFvbService= Co > mmon.h > > > b/Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbService= Co > mmon.h > > new file mode 100644 > > index 000000000000..e9d69e985814 > > --- /dev/null > > +++ > b/Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbService= Co > mmon.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 f= ield 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, FVB_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/SpiFvbService= M > m.h > > > b/Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbService= M > m.h > > new file mode 100644 > > index 000000000000..36af1130c8ee > > --- /dev/null > > +++ > b/Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbService= M > m.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/SpiFvbService= Sm > m.inf > > > b/Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbService= Sm > m.inf > > new file mode 100644 > > index 000000000000..bf1306f00201 > > --- /dev/null > > +++ > b/Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbService= Sm > m.inf > > @@ -0,0 +1,68 @@ > > +### @file > > +# Component description file for the Serial Flash device Runtime drive= r. > > +# > > +# 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-028B3EA21= 747 > > + 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 = the > 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 > ## CONSUMES > > + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize ## > CONSUMES > > + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize > ## CONSUMES > > + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize > ## CONSUMES > > + gIntelSiliconPkgTokenSpaceGuid.PcdFlashMicrocodeFvBase ## > CONSUMES > > + gIntelSiliconPkgTokenSpaceGuid.PcdFlashMicrocodeFvSize ## > CONSUMES > > + > > +[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/SpiFvbService= Sta > ndaloneMm.inf > > > b/Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbService= Sta > ndaloneMm.inf > > new file mode 100644 > > index 000000000000..b66233968247 > > --- /dev/null > > +++ > b/Silicon/Intel/IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbService= Sta > ndaloneMm.inf > > @@ -0,0 +1,67 @@ > > +### @file > > +# Component description file for the Serial Flash device Standalone MM > 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 0x0001001B > > + BASE_NAME =3D SpiFvbServiceStandaloneMm > > + FILE_GUID =3D E6313655-8BD0-4EAB-B319-AD5E212CE= 6AB > > + 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 = the > 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 > ## CONSUMES > > + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize ## > CONSUMES > > + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize > ## CONSUMES > > + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize > ## CONSUMES > > + gIntelSiliconPkgTokenSpaceGuid.PcdFlashMicrocodeFvBase ## > CONSUMES > > + gIntelSiliconPkgTokenSpaceGuid.PcdFlashMicrocodeFvSize ## > CONSUMES > > + > > +[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/Tp > mMeasurementLibNull.inf > > MicrocodeLib|UefiCpuPkg/Library/MicrocodeLib/MicrocodeLib.inf > > + > SpiFlashCommonLib|IntelSiliconPkg/Library/SpiFlashCommonLibNull/SpiFlas > hCommonLibNull.inf > > + > UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBo > otServicesTableLib.inf > > + > UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntry > Point.inf > > > > [LibraryClasses.common.PEIM] > > PeimEntryPoint|MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf > > @@ -61,8 +64,14 @@ [LibraryClasses.common.DXE_DRIVER] > > > > [LibraryClasses.common.DXE_SMM_DRIVER] > > > MemoryAllocationLib|MdePkg/Library/SmmMemoryAllocationLib/SmmMe > moryAllocationLib.inf > > + > MmServicesTableLib|MdePkg/Library/MmServicesTableLib/MmServicesTabl > eLib.inf > > > SmmServicesTableLib|MdePkg/Library/SmmServicesTableLib/SmmServicesT > ableLib.inf > > > > +[LibraryClasses.common.MM_STANDALONE] > > + > > > MemoryAllocationLib|StandaloneMmPkg/Library/StandaloneMmMemoryAll > ocationLib/StandaloneMmMemoryAllocationLib.inf > > + > MmServicesTableLib|MdePkg/Library/StandaloneMmServicesTableLib/Stan > daloneMmServicesTableLib.inf > > + > StandaloneMmDriverEntryPoint|MdePkg/Library/StandaloneMmDriverEntry > Point/StandaloneMmDriverEntryPoint.inf > > + > > > ########################################################## > ######################################### > > # > > # Components Section - list of the modules and components that will be > processed by compilation > > @@ -86,6 +95,8 @@ [Components] > > IntelSiliconPkg/Library/DxeSmbiosDataHobLib/DxeSmbiosDataHobLib.inf > > > IntelSiliconPkg/Feature/PcieSecurity/IntelPciDeviceSecurityDxe/IntelPciDe= vi > ceSecurityDxe.inf > > > IntelSiliconPkg/Feature/PcieSecurity/SamplePlatformDevicePolicyDxe/Sampl > ePlatformDevicePolicyDxe.inf > > + IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbServiceSmm.inf > > + > IntelSiliconPkg/Feature/Flash/SpiFvbService/SpiFvbServiceStandaloneMm.in > f > > IntelSiliconPkg/Feature/VTd/IntelVTdDxe/IntelVTdDxe.inf > > IntelSiliconPkg/Feature/VTd/IntelVTdDmarPei/IntelVTdDmarPei.inf > > IntelSiliconPkg/Feature/VTd/IntelVTdPmrPei/IntelVTdPmrPei.inf > > -- > > 2.28.0.windows.1