From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by spool.mail.gandi.net (Postfix) with ESMTPS id EE3D69413B5 for ; Fri, 26 Jan 2024 09:29:07 +0000 (UTC) DKIM-Signature: a=rsa-sha256; bh=tgewmXSg/XFMbtBAC6fVPQLBXm60CcioGp1o9vskpHo=; c=relaxed/simple; d=groups.io; h=ARC-Seal:ARC-Message-Signature:ARC-Authentication-Results:From:To:CC:Subject:Thread-Topic:Thread-Index:Date:Message-ID:References:In-Reply-To:Accept-Language:msip_labels:MIME-Version:Precedence:List-Subscribe:List-Help:Sender:List-Id:Mailing-List:Delivered-To:Reply-To:List-Unsubscribe-Post:List-Unsubscribe:Content-Language:Content-Type:Content-Transfer-Encoding; s=20140610; t=1706261346; v=1; b=pJu9T015Q4UA91WQaSvBVtf4necAU7DVXRyD4SDnetzQH04POzkMuBcWTF4Es1Cn3FY4AHOb mWSHGLp7wc93ydsqIlasqQBGOwPJ083k9KznSzPLb/3j2FJBKD0LqQIu3ByY+IKMdE7A6iZnBLu OK0CTOqZUJYUdG6t2jK2flQU= X-Received: by 127.0.0.2 with SMTP id M95DYY7687511xax4lEUAiBN; Fri, 26 Jan 2024 01:29:06 -0800 X-Received: from NAM10-DM6-obe.outbound.protection.outlook.com (NAM10-DM6-obe.outbound.protection.outlook.com [40.107.93.50]) by mx.groups.io with SMTP id smtpd.web10.12154.1706261345684078230 for ; Fri, 26 Jan 2024 01:29:05 -0800 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=ShWsVl6rR1uOmfEW0QwZns1r0e4HQaRjwCtNI14K80VCRk3FbL48VpLVkZ30ip1ypt5PgBsY8MY5PC2/1sGEAte0IGjeBo8OVMwHY3fMfMzSLOkdiyAvmKqzqiifIvVEbRE+Oat9jjwCBGPZL2njPL7riyF6QHodsP41kFLSizMKaWP70ah3Y1silk043PLYSz1pTJX2CePWj9tSgKNIex/X46nWohemXoWkg5YdF5J6IZhJa8l/N6Tb3UynmwPaCiMzdOYBaNkSQXdkRZNTk7sQv327iAhjzRqBfWfkYOhIa9AXHOKU+5bkZKn5p+WgwLldBPHO7TMFKuc4twJNng== 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-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=riNc2AFg9yifvAgriqiG/AOD5WLi0CvBa58W+NR2SLA=; b=nLjlLeNuIdxkUKEAXebBhS9cWrXVlu+ijAhkySLpmsvtcwCA30yIE6OLmmOv6FDKFpoypSn8MHKUzsKvCCUiGjmMjQXagGA3Tx2feq/DsUaL1tPAcaCjFerzSzDV15QoxKmaLiJRgwjHy46wqxvo7tAew0MhgjATpgfJPxpchWiuoHQ4oPELERkqfliJHWfWf4utbAJrxz/xCW+B7g0WJ3FM2fxf0cMaBoMDBaMaz29WiP5QZlrjjd+Vau+LIdespnvoV8kMWbubfeCZmtIWv3mgMDMThlA3JSyqir2obPiz1JXaH0R1SkeNfKxOvMUgfQKXPOFZh19TOspONIrs0g== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=amd.com; dmarc=pass action=none header.from=amd.com; dkim=pass header.d=amd.com; arc=none X-Received: from LV8PR12MB9452.namprd12.prod.outlook.com (2603:10b6:408:200::8) by SN7PR12MB7909.namprd12.prod.outlook.com (2603:10b6:806:340::21) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.7228.22; Fri, 26 Jan 2024 09:28:58 +0000 X-Received: from LV8PR12MB9452.namprd12.prod.outlook.com ([fe80::67bd:f1b9:58a3:d2e6]) by LV8PR12MB9452.namprd12.prod.outlook.com ([fe80::67bd:f1b9:58a3:d2e6%7]) with mapi id 15.20.7228.027; Fri, 26 Jan 2024 09:28:58 +0000 From: "Chang, Abner via groups.io" To: "Zhai, MingXin (Duke)" , "devel@edk2.groups.io" CC: "Xing, Eric" , "Fu, Igniculus" Subject: Re: [edk2-devel] [PATCH V2 21/32] AMD/VanGoghBoard: Check in SignedCapsule Thread-Topic: [PATCH V2 21/32] AMD/VanGoghBoard: Check in SignedCapsule Thread-Index: AQHaUB1bSf9oJM2l502C5rhjs5qz7LDr071Q Date: Fri, 26 Jan 2024 09:28:58 +0000 Message-ID: References: <20240126060050.1725-1-duke.zhai@amd.com> <20240126060050.1725-22-duke.zhai@amd.com> In-Reply-To: <20240126060050.1725-22-duke.zhai@amd.com> Accept-Language: en-US, zh-CN X-MS-Has-Attach: X-MS-TNEF-Correlator: msip_labels: MSIP_Label_4342314e-0df4-4b58-84bf-38bed6170a0f_ActionId=0e612577-07f3-4b19-8807-bb074a98d974;MSIP_Label_4342314e-0df4-4b58-84bf-38bed6170a0f_ContentBits=0;MSIP_Label_4342314e-0df4-4b58-84bf-38bed6170a0f_Enabled=true;MSIP_Label_4342314e-0df4-4b58-84bf-38bed6170a0f_Method=Standard;MSIP_Label_4342314e-0df4-4b58-84bf-38bed6170a0f_Name=General;MSIP_Label_4342314e-0df4-4b58-84bf-38bed6170a0f_SetDate=2024-01-26T09:28:12Z;MSIP_Label_4342314e-0df4-4b58-84bf-38bed6170a0f_SiteId=3dd8961f-e488-4e60-8e11-a82d994e183d; x-ms-publictraffictype: Email x-ms-traffictypediagnostic: LV8PR12MB9452:EE_|SN7PR12MB7909:EE_ x-ms-office365-filtering-correlation-id: f5eab444-e2a1-4311-9615-08dc1e513945 x-ms-exchange-senderadcheck: 1 x-ms-exchange-antispam-relay: 0 x-microsoft-antispam-message-info: rwIP9tpywqAPK2aVMNWlwKlHiWBgkrSGDTb9U2Kzc1JAMcAZvzqJx85Ht44umqmboVEvVhjAAXSJi59DBN8+j9Mji8e8Re8KEN28xLIZbJJyPLWfRMNniU0ZqDj2z6WTtgJHK7P0VXuBiKJxH7yv51PR91u9xuMhMA//BkZsRnWG/9c6VVSZBF43HIZnal811Nb8k0RRa0zHEsdMfwT4Dd6X9HBk7EfwfGXRwbmdzbhJRlWoMpChbrIlOcpePxpmlcSReBGNk1d23kE1tOp4Xi1SDdLLZAAt3818jJF1Jm9aOSAfJyO0E9fvS/Cf8d0k2LUwMAaP013viFh9ddGFFTn/CebDcR6sG7fMFWfv4wU5x3f/ZIVqjq87/BIiKNIsyRfBVeykpVMzJw5JN16Q7fW3iBqv+TeTrSJnifSwjHOM7V65t78vlDMJ/5MahVp0kmvV77QIrbej4vrutAi7XI8fcfR/D1QmTnPu38iq5CtL91xCC6h1cd/j5UHUs0DtmVQCclubdbThbHpW8W9WMuVQL1KBD1oeWXKhgcSQ4l341pFHiDXRKM+Ts+oycXSaHW5KE81QKbdm5eoF3HI+osSyUAjLJiMQR5x8WAILNIfmm+tEXAxi7n3y6kwoMp24lfbAHCzm1nmj14y1dLx20kOB9uPR1UpSlZRGZVdc0alYtVzmWKCh8BdGnVNGwqRgIuPyi9yQj7M7ae1TFiY8ow== x-ms-exchange-antispam-messagedata-chunkcount: 1 x-ms-exchange-antispam-messagedata-0: =?us-ascii?Q?1gabkME9tK/8Z86eT2RSwc5lOlMh48MHkE8TBUAm9RUooJ0GPa8/7+fYmbP0?= =?us-ascii?Q?Y32MUbg1niNtTUgdILYjQhq/o6OsqGblNt/Ah7yDp3pTMnuaXAjEei4hN2d7?= =?us-ascii?Q?0S/c5AhsC3iPGXV9SzbHKOnrNqpJtmywFeU2sXE3S5ucbY4wQnkUK4IYx3U/?= =?us-ascii?Q?3Ts3yYNAcaqnun8xtiPjoKyXK0PIiL6c+PyjtEPzIwPDUUtMn7uRg/CYCHHA?= =?us-ascii?Q?7NoPBTNU5MQOUEt5t0zZFgUKiqe2yPlPcsARtWB2vVcRnT0xC3gwa7x53eSi?= =?us-ascii?Q?vKmV7Etkr3cf2531Vo56jROgQneSAUu/9Lyx2zDsQSXG0KpCwVTXu+5I2uLW?= =?us-ascii?Q?5p++DvRp4AUJShq12INBX8NpkLaBUtGPcmwddThQxNR2Zlf6cg0V7BWOl6WJ?= =?us-ascii?Q?/4tB9OY+PC+7n9n9dNv8AoFhIKwo4yVCThDhkNFPWTB7KjHJIou01eyflPbE?= =?us-ascii?Q?BkfhHlSoLHUiJM6OgLZl1UUYYv/FVklTg02a091M4JQFda6bAAcTWcgotE2v?= =?us-ascii?Q?fd1Mx6YPoTmwWtOgw7u8Kk/v9+GmbI9hOhhqbRgozuST9N8iDGUmTcmfXLNC?= =?us-ascii?Q?+uDaulm6MRziZ3rE8d0WVqg4snSlsSvpgCH9OEP4pbRXXqRKOnEXvTKON1gT?= =?us-ascii?Q?ocNlSW89s4PRjL2udBgu56evjHjki/EtT94y8MaqFY2uwNmdzE12eEOC7WNp?= =?us-ascii?Q?8gsXgY3fNL+jNi0IXPmqELXh8zGMeW5qBN0jpfpWcUMzQNwqtzpzmpakWVn/?= =?us-ascii?Q?bn7J6DsmhbyFgcpyJ5QtGaohrVwRjHDfOgJgr2tudHFaMs1zcUDZ17uwFNUD?= =?us-ascii?Q?A3zFNP0cFJptRh2EdCEATNCiXiSoWuANcXO46BxufOCUCM7O1r6zOhteNf7j?= =?us-ascii?Q?5UJF6VVO4lfre5N6X3mUd5KCR1aYrzmwvIhg5MlQHXX2P+RUgwIksF4E4Tet?= =?us-ascii?Q?AldTgwkQq03m7ojE/5UmwyGsdxJLuMTohXdmMWjfm5p015icqNYyFBEJVuj7?= =?us-ascii?Q?bWVbLvRd3JoX8Avv8MpNNICnghrD05YYwj9r2DGH4DWrnP5YBnVSNuNNOevS?= =?us-ascii?Q?shuxgFpnK1Dq8jWmQOfVLeCqjfyFgD57J6HovBVEIw3gP/zh/GcbNX2vHd81?= =?us-ascii?Q?xGunIDWkdWcZSDSahW/nLPhdhHgwoL9UcA1KhznmOK1W91GLaaR6/6gFYJSt?= =?us-ascii?Q?HUnC1F8Zs5QgyPDGbI3EaM1WACwRoPsobCvdHQxQzVJs94ZHp1na4EIH9RF2?= =?us-ascii?Q?ifhO1dhPK98Ckga1cb9AuZXzVsb1d2VVRBq6KrQJQODR4w/dk89tfHmWcUwC?= =?us-ascii?Q?/SIsNR5TSDcz+5RCtD5++R340nQ6Du0s20qAZANOR0Sro04/TeC2vLCyrADm?= =?us-ascii?Q?rbUJ9qZ/243BpoLeYY160fIp6x6JZl6AFsaDcH5ufwzBGykE5zRu7JnbYmK3?= =?us-ascii?Q?8kKCQeQHX4LGYqpq7JjDJpAJvc7fhMqLOkn+C1VdCrcFCW21qzhX4bsZr4Bq?= =?us-ascii?Q?V5P2KoLjHMTxKQfHtxW4LzjQDRB0aoFTi6e8ASAKr/ORnTMpxRqFHIS1T3Gv?= =?us-ascii?Q?JTDsdLxa1nYGwJ0Ny4yFYyhzbPbSdCKLRqS7W1AT?= MIME-Version: 1.0 X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-AuthSource: LV8PR12MB9452.namprd12.prod.outlook.com X-MS-Exchange-CrossTenant-Network-Message-Id: f5eab444-e2a1-4311-9615-08dc1e513945 X-MS-Exchange-CrossTenant-originalarrivaltime: 26 Jan 2024 09:28:58.1647 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-mailboxtype: HOSTED X-MS-Exchange-CrossTenant-userprincipalname: KjluHyCrwUVW2YGqkED57ZZ9Zt4bV/xGMXS3jeyfIetOY2cgTxBnKChECqurBBC1ydrVBAkorpUndY4ikHJxEQ== X-MS-Exchange-Transport-CrossTenantHeadersStamped: SN7PR12MB7909 Precedence: Bulk List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,abner.chang@amd.com List-Unsubscribe-Post: List-Unsubscribe=One-Click List-Unsubscribe: X-Gm-Message-State: d12Aw0QtR25tkBq3uNSMSdt7x7686176AA= Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable X-GND-Status: LEGIT Authentication-Results: spool.mail.gandi.net; dkim=pass header.d=groups.io header.s=20140610 header.b=pJu9T015; dmarc=none; spf=pass (spool.mail.gandi.net: domain of bounce@groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce@groups.io [AMD Official Use Only - General] > -----Original Message----- > From: Zhai, MingXin (Duke) > Sent: Friday, January 26, 2024 2:01 PM > To: devel@edk2.groups.io > Cc: Xing, Eric ; Zhai, MingXin (Duke) > ; Fu, Igniculus ; Chang, > Abner > Subject: [PATCH V2 21/32] AMD/VanGoghBoard: Check in SignedCapsule > > From: Duke Zhai > > BZ #:4640 > In V2: Improve coding style. > 1.Remove the leading underscore and use double underscore at trailing i= n C > header files. > 2.Remove old tianocore licenses and redundant license description. > 3.Improve coding style. For example: remove space between @param. > > In V1: > Initial SignedCapsule module for Signed Capsule. > Produce FMP instance to update system firmware. > > Signed-off-by: Ken Yao > Cc: Eric Xing > Cc: Duke Zhai > Cc: Igniculus Fu > Cc: Abner Chang > --- > .../BaseTools/Source/Python/GenFds/Capsule.py | 253 +++ > .../SystemFirmwareUpdate/ParseConfigProfile.c | 231 +++ > .../SystemFirmwareCommonDxe.c | 371 +++++ > .../SystemFirmwareUpdate/SystemFirmwareDxe.h | 421 +++++ > .../SystemFirmwareUpdateDxe.c | 1426 +++++++++++++++++ > .../SystemFirmwareUpdateDxe.inf | 91 ++ > .../SystemFirmwareUpdateDxe.uni | 15 + > .../SystemFirmwareUpdateDxeExtra.uni | 15 + > 8 files changed, 2823 insertions(+) > create mode 100644 > Platform/AMD/VanGoghBoard/Override/edk2/BaseTools/Source/Python/Ge > nFds/Capsule.py > create mode 100644 > Platform/AMD/VanGoghBoard/Override/edk2/SignedCapsulePkg/Universal/S > ystemFirmwareUpdate/ParseConfigProfile.c > create mode 100644 > Platform/AMD/VanGoghBoard/Override/edk2/SignedCapsulePkg/Universal/S > ystemFirmwareUpdate/SystemFirmwareCommonDxe.c > create mode 100644 > Platform/AMD/VanGoghBoard/Override/edk2/SignedCapsulePkg/Universal/S > ystemFirmwareUpdate/SystemFirmwareDxe.h > create mode 100644 > Platform/AMD/VanGoghBoard/Override/edk2/SignedCapsulePkg/Universal/S > ystemFirmwareUpdate/SystemFirmwareUpdateDxe.c > create mode 100644 > Platform/AMD/VanGoghBoard/Override/edk2/SignedCapsulePkg/Universal/S > ystemFirmwareUpdate/SystemFirmwareUpdateDxe.inf > create mode 100644 > Platform/AMD/VanGoghBoard/Override/edk2/SignedCapsulePkg/Universal/S > ystemFirmwareUpdate/SystemFirmwareUpdateDxe.uni > create mode 100644 > Platform/AMD/VanGoghBoard/Override/edk2/SignedCapsulePkg/Universal/S > ystemFirmwareUpdate/SystemFirmwareUpdateDxeExtra.uni > > diff --git > a/Platform/AMD/VanGoghBoard/Override/edk2/BaseTools/Source/Python/G > enFds/Capsule.py > b/Platform/AMD/VanGoghBoard/Override/edk2/BaseTools/Source/Python/G > enFds/Capsule.py > new file mode 100644 > index 0000000000..0ec0b3ca43 > --- /dev/null > +++ > b/Platform/AMD/VanGoghBoard/Override/edk2/BaseTools/Source/Python/G > enFds/Capsule.py > @@ -0,0 +1,253 @@ > +## @file > +# generate capsule > +# > +# Copyright (C) 2024 Advanced Micro Devices, Inc. > +# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved. > +# > +# SPDX-License-Identifier: BSD-2-Clause-Patent > +# > + > +## > +# Import Modules > +# > +from __future__ import absolute_import > +from .GenFdsGlobalVariable import GenFdsGlobalVariable, FindExtendTool > +from CommonDataClass.FdfClass import CapsuleClassObject > +import Common.LongFilePathOs as os > +from io import BytesIO > +from Common.Misc import SaveFileOnChange, PackGUID > +import uuid > +from struct import pack > +from Common import EdkLogger > +from Common.BuildToolError import GENFDS_ERROR > +from Common.DataType import TAB_LINE_BREAK > + > +WIN_CERT_REVISION =3D 0x0200 > +WIN_CERT_TYPE_EFI_GUID =3D 0x0EF1 > +EFI_CERT_TYPE_PKCS7_GUID =3D uuid.UUID('{4aafd29d-68df-49ee-8aa9- > 347d375665a7}') > +EFI_CERT_TYPE_RSA2048_SHA256_GUID =3D uuid.UUID('{a7717414-c616- > 4977-9420-844712a735bf}') > + > +## create inf file describes what goes into capsule and call GenFv to ge= nerate > capsule > +# > +# > +class Capsule (CapsuleClassObject): > + ## The constructor > + # > + # @param self The object pointer > + # > + def __init__(self): > + CapsuleClassObject.__init__(self) > + # For GenFv > + self.BlockSize =3D None > + # For GenFv > + self.BlockNum =3D None > + self.CapsuleName =3D None > + > + ## Generate FMP capsule > + # > + # @retval string Generated Capsule file path > + # > + def GenFmpCapsule(self): > + # > + # Generate capsule header > + # typedef struct { > + # EFI_GUID CapsuleGuid; > + # UINT32 HeaderSize; > + # UINT32 Flags; > + # UINT32 CapsuleImageSize; > + # } EFI_CAPSULE_HEADER; > + # > + Header =3D BytesIO() > + # > + # Use FMP capsule GUID: 6DCBD5ED-E82D-4C44-BDA1-7194199AD92A > + # > + Header.write(PackGUID('6DCBD5ED-E82D-4C44-BDA1- > 7194199AD92A'.split('-'))) > + HdrSize =3D 0 > + if 'CAPSULE_HEADER_SIZE' in self.TokensDict: > + Header.write(pack('=3DI', int(self.TokensDict['CAPSULE_HEADE= R_SIZE'], > 16))) > + HdrSize =3D int(self.TokensDict['CAPSULE_HEADER_SIZE'], 16) > + else: > + Header.write(pack('=3DI', 0x20)) > + HdrSize =3D 0x20 > + Flags =3D 0 > + if 'CAPSULE_FLAGS' in self.TokensDict: > + for flag in self.TokensDict['CAPSULE_FLAGS'].split(','): > + flag =3D flag.strip() > + if flag =3D=3D 'PopulateSystemTable': > + Flags |=3D 0x00010000 | 0x00020000 > + elif flag =3D=3D 'PersistAcrossReset': > + Flags |=3D 0x00010000 > + elif flag =3D=3D 'InitiateReset': > + Flags |=3D 0x00040000 > + if 'OEM_CAPSULE_FLAGS' in self.TokensDict: > + Flags |=3D int(self.TokensDict['OEM_CAPSULE_FLAGS'],16) > + Header.write(pack('=3DI', Flags)) > + # > + # typedef struct { > + # UINT32 Version; > + # UINT16 EmbeddedDriverCount; > + # UINT16 PayloadItemCount; > + # // UINT64 ItemOffsetList[]; > + # } EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER; > + # > + FwMgrHdr =3D BytesIO() > + if 'CAPSULE_HEADER_INIT_VERSION' in self.TokensDict: > + FwMgrHdr.write(pack('=3DI', > int(self.TokensDict['CAPSULE_HEADER_INIT_VERSION'], 16))) > + else: > + FwMgrHdr.write(pack('=3DI', 0x00000001)) > + FwMgrHdr.write(pack('=3DHH', len(self.CapsuleDataList), > len(self.FmpPayloadList))) > + FwMgrHdrSize =3D > 4+2+2+8*(len(self.CapsuleDataList)+len(self.FmpPayloadList)) > + > + # > + # typedef struct _WIN_CERTIFICATE { > + # UINT32 dwLength; > + # UINT16 wRevision; > + # UINT16 wCertificateType; > + # //UINT8 bCertificate[ANYSIZE_ARRAY]; > + # } WIN_CERTIFICATE; > + # > + # typedef struct _WIN_CERTIFICATE_UEFI_GUID { > + # WIN_CERTIFICATE Hdr; > + # EFI_GUID CertType; > + # //UINT8 CertData[ANYSIZE_ARRAY]; > + # } WIN_CERTIFICATE_UEFI_GUID; > + # > + # typedef struct { > + # UINT64 MonotonicCount; > + # WIN_CERTIFICATE_UEFI_GUID AuthInfo; > + # } EFI_FIRMWARE_IMAGE_AUTHENTICATION; > + # > + # typedef struct _EFI_CERT_BLOCK_RSA_2048_SHA256 { > + # EFI_GUID HashType; > + # UINT8 PublicKey[256]; > + # UINT8 Signature[256]; > + # } EFI_CERT_BLOCK_RSA_2048_SHA256; > + # > + > + PreSize =3D FwMgrHdrSize > + Content =3D BytesIO() > + for driver in self.CapsuleDataList: > + FileName =3D driver.GenCapsuleSubItem() > + FwMgrHdr.write(pack('=3DQ', PreSize)) > + PreSize +=3D os.path.getsize(FileName) > + File =3D open(FileName, 'rb') > + Content.write(File.read()) > + File.close() > + for fmp in self.FmpPayloadList: > + if fmp.Existed: > + FwMgrHdr.write(pack('=3DQ', PreSize)) > + PreSize +=3D len(fmp.Buffer) > + Content.write(fmp.Buffer) > + continue > + if fmp.ImageFile: > + for Obj in fmp.ImageFile: > + fmp.ImageFile =3D Obj.GenCapsuleSubItem() > + if fmp.VendorCodeFile: > + for Obj in fmp.VendorCodeFile: > + fmp.VendorCodeFile =3D Obj.GenCapsuleSubItem() > + if fmp.Certificate_Guid: > + ExternalTool, ExternalOption =3D FindExtendTool([], > GenFdsGlobalVariable.ArchList, fmp.Certificate_Guid) > + CmdOption =3D '' > + CapInputFile =3D fmp.ImageFile > + if not os.path.isabs(fmp.ImageFile): > + CapInputFile =3D os.path.join(GenFdsGlobalVariable.W= orkSpaceDir, > fmp.ImageFile) > + CapOutputTmp =3D os.path.join(GenFdsGlobalVariable.FvDir= , > self.UiCapsuleName) + '.tmp' > + if ExternalTool is None: > + EdkLogger.error("GenFds", GENFDS_ERROR, "No tool fou= nd with > GUID %s" % fmp.Certificate_Guid) > + else: > + CmdOption +=3D ExternalTool > + if ExternalOption: > + CmdOption =3D CmdOption + ' ' + ExternalOption > + CmdOption +=3D ' -e ' + ' --monotonic-count ' + > str(fmp.MonotonicCount) + ' -o ' + CapOutputTmp + ' ' + CapInputFile > + CmdList =3D CmdOption.split() > + GenFdsGlobalVariable.CallExternalTool(CmdList, "Failed t= o generate > FMP auth capsule") > + if uuid.UUID(fmp.Certificate_Guid) =3D=3D EFI_CERT_TYPE_= PKCS7_GUID: > + dwLength =3D 4 + 2 + 2 + 16 + os.path.getsize(CapOut= putTmp) - > os.path.getsize(CapInputFile) > + else: > + dwLength =3D 4 + 2 + 2 + 16 + 16 + 256 + 256 > + fmp.ImageFile =3D CapOutputTmp > + AuthData =3D [fmp.MonotonicCount, dwLength, > WIN_CERT_REVISION, WIN_CERT_TYPE_EFI_GUID, fmp.Certificate_Guid] > + fmp.Buffer =3D fmp.GenCapsuleSubItem(AuthData) > + else: > + fmp.Buffer =3D fmp.GenCapsuleSubItem() > + FwMgrHdr.write(pack('=3DQ', PreSize)) > + PreSize +=3D len(fmp.Buffer) > + Content.write(fmp.Buffer) > + BodySize =3D len(FwMgrHdr.getvalue()) + len(Content.getvalue()) > + Header.write(pack('=3DI', HdrSize + BodySize)) > + # > + # The real capsule header structure is 28 bytes > + # > + Header.write(b'\x00'*(HdrSize-28)) > + Header.write(FwMgrHdr.getvalue()) > + Header.write(Content.getvalue()) > + # > + # Generate FMP capsule file > + # > + CapOutputFile =3D os.path.join(GenFdsGlobalVariable.FvDir, > self.UiCapsuleName) + '.Cap' > + SaveFileOnChange(CapOutputFile, Header.getvalue(), True) > + return CapOutputFile > + > + ## Generate capsule > + # > + # @param self The object pointer > + # @retval string Generated Capsule file path > + # > + def GenCapsule(self): > + if self.UiCapsuleName.upper() + 'cap' in > GenFdsGlobalVariable.ImageBinDict: > + return > GenFdsGlobalVariable.ImageBinDict[self.UiCapsuleName.upper() + 'cap'] > + > + GenFdsGlobalVariable.InfLogger( "\nGenerate %s Capsule" > %self.UiCapsuleName) > + if ('CAPSULE_GUID' in self.TokensDict and > + uuid.UUID(self.TokensDict['CAPSULE_GUID']) =3D=3D > uuid.UUID('6DCBD5ED-E82D-4C44-BDA1-7194199AD92A')): > + return self.GenFmpCapsule() > + > + CapInfFile =3D self.GenCapInf() > + CapInfFile.append("[files]" + TAB_LINE_BREAK) > + CapFileList =3D [] > + for CapsuleDataObj in self.CapsuleDataList: > + CapsuleDataObj.CapsuleName =3D self.CapsuleName > + FileName =3D CapsuleDataObj.GenCapsuleSubItem() > + CapsuleDataObj.CapsuleName =3D None > + CapFileList.append(FileName) > + CapInfFile.append("EFI_FILE_NAME =3D " + \ > + FileName + \ > + TAB_LINE_BREAK) > + SaveFileOnChange(self.CapInfFileName, ''.join(CapInfFile), False= ) > + # > + # Call GenFv tool to generate capsule > + # > + CapOutputFile =3D os.path.join(GenFdsGlobalVariable.FvDir, > self.UiCapsuleName) > + CapOutputFile =3D CapOutputFile + '.Cap' > + GenFdsGlobalVariable.GenerateFirmwareVolume( > + CapOutputFile, > + [self.CapInfFileName], > + Capsule=3DTrue, > + FfsList=3DCapFileList > + ) > + > + GenFdsGlobalVariable.VerboseLogger( "\nGenerate %s Capsule > Successfully" %self.UiCapsuleName) > + GenFdsGlobalVariable.SharpCounter =3D 0 > + GenFdsGlobalVariable.ImageBinDict[self.UiCapsuleName.upper() + '= cap'] > =3D CapOutputFile > + return CapOutputFile > + > + ## Generate inf file for capsule > + # > + # @param self The object pointer > + # @retval file inf file object > + # > + def GenCapInf(self): > + self.CapInfFileName =3D os.path.join(GenFdsGlobalVariable.FvDir, > + self.UiCapsuleName + "_Cap" + '.inf'= ) > + CapInfFile =3D [] > + > + CapInfFile.append("[options]" + TAB_LINE_BREAK) > + > + for Item in self.TokensDict: > + CapInfFile.append("EFI_" + \ > + Item + \ > + ' =3D ' + \ > + self.TokensDict[Item] + \ > + TAB_LINE_BREAK) > + > + return CapInfFile > diff --git > a/Platform/AMD/VanGoghBoard/Override/edk2/SignedCapsulePkg/Universal > /SystemFirmwareUpdate/ParseConfigProfile.c > b/Platform/AMD/VanGoghBoard/Override/edk2/SignedCapsulePkg/Universa > l/SystemFirmwareUpdate/ParseConfigProfile.c > new file mode 100644 > index 0000000000..b57586a267 > --- /dev/null > +++ > b/Platform/AMD/VanGoghBoard/Override/edk2/SignedCapsulePkg/Universa > l/SystemFirmwareUpdate/ParseConfigProfile.c > @@ -0,0 +1,231 @@ > +/** @file > + Implements ParseConfigProfile.c > + > + Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved. > + SPDX-License-Identifier: BSD-2-Clause-Patent > + > +**/ Please put AMD copy right under Intel's. Thanks Abner > + > +/** @file > + Parse the INI configuration file and pass the information to the updat= e driver > + so that the driver can perform update accordingly. > + > + Copyright (c) 2016 - 2017, Intel Corporation. All rights reserved.
> + > + This program and the accompanying materials > + are licensed and made available under the terms and conditions > + of the BSD License which accompanies this distribution. The > + full text of the license may be found at > + http://opensource.org/licenses/bsd-license.php > + > + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" > BASIS, > + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER > EXPRESS OR IMPLIED. > + > +**/ > + > +#include "SystemFirmwareDxe.h" > +#include > +#include > + > +#define MAX_LINE_LENGTH 512 > + > +/** > + Parse Config data file to get the updated data array. > + > + @param[in] DataBuffer Config raw file buffer. > + @param[in] BufferSize Size of raw buffer. > + @param[in, out] ConfigHeader Pointer to the config header. > + @param[in, out] UpdateArray Pointer to the config of update data. > + > + @retval EFI_NOT_FOUND No config data is found. > + @retval EFI_OUT_OF_RESOURCES No enough memory is allocated. > + @retval EFI_SUCCESS Parse the config file successfully. > + > +**/ > +EFI_STATUS > +ParseUpdateDataFile ( > + IN UINT8 *DataBuffer, > + IN UINTN BufferSize, > + IN OUT CONFIG_HEADER *ConfigHeader, > + IN OUT UPDATE_CONFIG_DATA **UpdateArray > + ) > +{ > + EFI_STATUS Status; > + CHAR8 *SectionName; > + CHAR8 Entry[MAX_LINE_LENGTH]; > + UINTN Num; > + UINT64 Num64; > + UINTN Index; > + EFI_GUID FileGuid; > + VOID *Context; > + > + // > + // First process the data buffer and get all sections and entries > + // > + Context =3D OpenIniFile (DataBuffer, BufferSize); > + if (Context =3D=3D NULL) { > + return EFI_INVALID_PARAMETER; > + } > + > + // > + // Now get NumOfUpdate > + // > + Status =3D GetDecimalUintnFromDataFile ( > + Context, > + "Head", > + "NumOfUpdate", > + &Num > + ); > + if (EFI_ERROR (Status) || (Num =3D=3D 0)) { > + DEBUG ((DEBUG_ERROR, "NumOfUpdate not found\n")); > + CloseIniFile (Context); > + return EFI_NOT_FOUND; > + } > + > + ConfigHeader->NumOfUpdates =3D Num; > + *UpdateArray =3D AllocateZeroPool ((sizeof (UPDATE_CONFI= G_DATA) * > Num)); > + if (*UpdateArray =3D=3D NULL) { > + CloseIniFile (Context); > + return EFI_OUT_OF_RESOURCES; > + } > + > + for (Index =3D 0; Index < ConfigHeader->NumOfUpdates; Index++) { > + // > + // Get the section name of each update > + // > + AsciiStrCpyS (Entry, MAX_LINE_LENGTH, "Update"); > + AsciiValueToStringS ( > + Entry + AsciiStrnLenS (Entry, MAX_LINE_LENGTH), > + MAX_LINE_LENGTH - AsciiStrnLenS (Entry, MAX_LINE_LENGTH), > + 0, > + Index, > + 0 > + ); > + Status =3D GetStringFromDataFile ( > + Context, > + "Head", > + Entry, > + &SectionName > + ); > + if (EFI_ERROR (Status) || (SectionName =3D=3D NULL)) { > + DEBUG ((DEBUG_ERROR, "[%d] %a not found\n", Index, Entry)); > + CloseIniFile (Context); > + return EFI_NOT_FOUND; > + } > + > + // > + // The section name of this update has been found. > + // Now looks for all the config data of this update > + // > + (*UpdateArray)[Index].Index =3D Index; > + > + // > + // FirmwareType > + // > + Status =3D GetDecimalUintnFromDataFile ( > + Context, > + SectionName, > + "FirmwareType", > + &Num > + ); > + if (EFI_ERROR (Status)) { > + CloseIniFile (Context); > + DEBUG ((DEBUG_ERROR, "[%d] FirmwareType not found\n", Index)); > + return EFI_NOT_FOUND; > + } > + > + (*UpdateArray)[Index].FirmwareType =3D > (PLATFORM_FIRMWARE_TYPE)Num; > + > + // > + // AddressType > + // > + Status =3D GetDecimalUintnFromDataFile ( > + Context, > + SectionName, > + "AddressType", > + &Num > + ); > + if (EFI_ERROR (Status)) { > + CloseIniFile (Context); > + DEBUG ((DEBUG_ERROR, "[%d] AddressType not found\n", Index)); > + return EFI_NOT_FOUND; > + } > + > + (*UpdateArray)[Index].AddressType =3D (FLASH_ADDRESS_TYPE)Num; > + > + // > + // BaseAddress > + // > + Status =3D GetHexUint64FromDataFile ( > + Context, > + SectionName, > + "BaseAddress", > + &Num64 > + ); > + if (EFI_ERROR (Status)) { > + CloseIniFile (Context); > + DEBUG ((DEBUG_ERROR, "[%d] BaseAddress not found\n", Index)); > + return EFI_NOT_FOUND; > + } > + > + (*UpdateArray)[Index].BaseAddress =3D (EFI_PHYSICAL_ADDRESS)Num64; > + > + // > + // FileBuid > + // > + Status =3D GetGuidFromDataFile ( > + Context, > + SectionName, > + "FileGuid", > + &FileGuid > + ); > + if (EFI_ERROR (Status)) { > + CloseIniFile (Context); > + DEBUG ((DEBUG_ERROR, "[%d] FileGuid not found\n", Index)); > + return EFI_NOT_FOUND; > + } > + > + CopyGuid (&((*UpdateArray)[Index].FileGuid), &FileGuid); > + > + // > + // Length > + // > + Status =3D GetHexUintnFromDataFile ( > + Context, > + SectionName, > + "Length", > + &Num > + ); > + if (EFI_ERROR (Status)) { > + CloseIniFile (Context); > + DEBUG ((DEBUG_ERROR, "[%d] Length not found\n", Index)); > + return EFI_NOT_FOUND; > + } > + > + (*UpdateArray)[Index].Length =3D (UINTN)Num; > + > + // > + // ImageOffset > + // > + Status =3D GetHexUintnFromDataFile ( > + Context, > + SectionName, > + "ImageOffset", > + &Num > + ); > + if (EFI_ERROR (Status)) { > + CloseIniFile (Context); > + DEBUG ((DEBUG_ERROR, "[%d] ImageOffset not found\n", Index)); > + return EFI_NOT_FOUND; > + } > + > + (*UpdateArray)[Index].ImageOffset =3D (UINTN)Num; > + } > + > + // > + // Now all configuration data got. Free those temporary buffers > + // > + CloseIniFile (Context); > + > + return EFI_SUCCESS; > +} > diff --git > a/Platform/AMD/VanGoghBoard/Override/edk2/SignedCapsulePkg/Universal > /SystemFirmwareUpdate/SystemFirmwareCommonDxe.c > b/Platform/AMD/VanGoghBoard/Override/edk2/SignedCapsulePkg/Universa > l/SystemFirmwareUpdate/SystemFirmwareCommonDxe.c > new file mode 100644 > index 0000000000..05a36162d3 > --- /dev/null > +++ > b/Platform/AMD/VanGoghBoard/Override/edk2/SignedCapsulePkg/Universa > l/SystemFirmwareUpdate/SystemFirmwareCommonDxe.c > @@ -0,0 +1,371 @@ > +/** @file > + Produce FMP instance for system firmware. > + > + Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved. > + Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.
> + SPDX-License-Identifier: BSD-2-Clause-Patent > + > +**/ > + > +#include "SystemFirmwareDxe.h" > + > +EFI_GUID gSystemFmpLastAttemptVariableGuid =3D > SYSTEM_FMP_LAST_ATTEMPT_VARIABLE_GUID; > +EFI_GUID gSystemFmpProtocolGuid =3D > SYSTEM_FMP_PROTOCOL_GUID; > + > +EFI_FIRMWARE_MANAGEMENT_PROTOCOL > mFirmwareManagementProtocol =3D { > + FmpGetImageInfo, > + FmpGetImage, > + FmpSetImage, > + FmpCheckImage, > + FmpGetPackageInfo, > + FmpSetPackageInfo > +}; > + > +/** > + Returns information about the current firmware image(s) of the device. > + > + This function allows a copy of the current firmware image to be create= d and > saved. > + The saved copy could later been used, for example, in firmware image > recovery or rollback. > + > + @param[in] This A pointer to the > EFI_FIRMWARE_MANAGEMENT_PROTOCOL instance. > + @param[in, out] ImageInfoSize A pointer to the size, in bytes, of= the > ImageInfo buffer. > + On input, this is the size of the b= uffer allocated by the > caller. > + On output, it is the size of the bu= ffer returned by the > firmware > + if the buffer was large enough, or = the size of the buffer > needed > + to contain the image(s) information= if the buffer was too > small. > + @param[in, out] ImageInfo A pointer to the buffer in which fi= rmware > places the current image(s) > + information. The information is an = array of > EFI_FIRMWARE_IMAGE_DESCRIPTORs. > + @param[out] DescriptorVersion A pointer to the location in which > firmware returns the version number > + associated with the EFI_FIRMWARE_IM= AGE_DESCRIPTOR. > + @param[out] DescriptorCount A pointer to the location in which > firmware returns the number of > + descriptors or firmware images with= in this device. > + @param[out] DescriptorSize A pointer to the location in which = firmware > returns the size, in bytes, > + of an individual EFI_FIRMWARE_IMAGE= _DESCRIPTOR. > + @param[out] PackageVersion A version number that represents al= l the > firmware images in the device. > + The format is vendor specific and n= ew version must have a > greater value > + than the old version. If PackageVer= sion is not supported, > the value is > + 0xFFFFFFFF. A value of 0xFFFFFFFE i= ndicates that package > version comparison > + is to be performed using PackageVer= sionName. A value of > 0xFFFFFFFD indicates > + that package version update is in p= rogress. > + @param[out] PackageVersionName A pointer to a pointer to a null- > terminated string representing the > + package version name. The buffer is= allocated by this > function with > + AllocatePool(), and it is the calle= r's responsibility to free it > with a call > + to FreePool(). > + > + @retval EFI_SUCCESS The device was successfully updated= with the > new image. > + @retval EFI_BUFFER_TOO_SMALL The ImageInfo buffer was too small. > The current buffer size > + needed to hold the image(s) informa= tion is returned in > ImageInfoSize. > + @retval EFI_INVALID_PARAMETER ImageInfoSize is NULL. > + @retval EFI_DEVICE_ERROR Valid information could not be retu= rned. > Possible corrupted image. > + > +**/ > +EFI_STATUS > +EFIAPI > +FmpGetImageInfo ( > + IN EFI_FIRMWARE_MANAGEMENT_PROTOCOL *This, > + IN OUT UINTN *ImageInfoSize, > + IN OUT EFI_FIRMWARE_IMAGE_DESCRIPTOR *ImageInfo, > + OUT UINT32 *DescriptorVersion, > + OUT UINT8 *DescriptorCount, > + OUT UINTN *DescriptorSize, > + OUT UINT32 *PackageVersion, > + OUT CHAR16 **PackageVersionName > + ) > +{ > + SYSTEM_FMP_PRIVATE_DATA *SystemFmpPrivate; > + EDKII_SYSTEM_FIRMWARE_IMAGE_DESCRIPTOR *ImageDescriptor; > + > + SystemFmpPrivate =3D SYSTEM_FMP_PRIVATE_DATA_FROM_FMP (This); > + > + if (ImageInfoSize =3D=3D NULL) { > + return EFI_INVALID_PARAMETER; > + } > + > + if (*ImageInfoSize < sizeof (EFI_FIRMWARE_IMAGE_DESCRIPTOR) * > SystemFmpPrivate->DescriptorCount) { > + *ImageInfoSize =3D sizeof (EFI_FIRMWARE_IMAGE_DESCRIPTOR) * > SystemFmpPrivate->DescriptorCount; > + return EFI_BUFFER_TOO_SMALL; > + } > + > + if ((ImageInfo =3D=3D NULL) || > + (DescriptorVersion =3D=3D NULL) || > + (DescriptorCount =3D=3D NULL) || > + (DescriptorSize =3D=3D NULL) || > + (PackageVersion =3D=3D NULL) || > + (PackageVersionName =3D=3D NULL)) > + { > + return EFI_INVALID_PARAMETER; > + } > + > + *ImageInfoSize =3D sizeof (EFI_FIRMWARE_IMAGE_DESCRIPTOR) * > SystemFmpPrivate->DescriptorCount; > + *DescriptorSize =3D sizeof (EFI_FIRMWARE_IMAGE_DESCRIPTOR); > + *DescriptorCount =3D SystemFmpPrivate->DescriptorCount; > + *DescriptorVersion =3D EFI_FIRMWARE_IMAGE_DESCRIPTOR_VERSION; > + > + // > + // supports 1 ImageInfo descriptor > + // > + ImageDescriptor =3D SystemFmpPrivate->ImageDescriptor; > + ImageInfo->ImageIndex =3D ImageDescriptor->ImageIndex; > + CopyGuid (&ImageInfo->ImageTypeId, &ImageDescriptor->ImageTypeId); > + ImageInfo->ImageId =3D ImageDescriptor->ImageId; > + if (ImageDescriptor->ImageIdNameStringOffset !=3D 0) { > + ImageInfo->ImageIdName =3D (CHAR16 *)((UINTN)ImageDescriptor + > ImageDescriptor->ImageIdNameStringOffset); > + } else { > + ImageInfo->ImageIdName =3D NULL; > + } > + > + ImageInfo->Version =3D ImageDescriptor->Version; > + if (ImageDescriptor->VersionNameStringOffset !=3D 0) { > + ImageInfo->VersionName =3D (CHAR16 *)((UINTN)ImageDescriptor + > ImageDescriptor->VersionNameStringOffset); > + } else { > + ImageInfo->VersionName =3D NULL; > + } > + > + ImageInfo->Size =3D (UINTN)ImageDescriptor->Siz= e; > + ImageInfo->AttributesSupported =3D ImageDescriptor- > >AttributesSupported; > + ImageInfo->AttributesSetting =3D ImageDescriptor->Attributes= Setting; > + ImageInfo->Compatibilities =3D ImageDescriptor->Compatibil= ities; > + ImageInfo->LowestSupportedImageVersion =3D ImageDescriptor- > >LowestSupportedImageVersion; > + ImageInfo->LastAttemptVersion =3D SystemFmpPrivate- > >LastAttempt.LastAttemptVersion; > + ImageInfo->LastAttemptStatus =3D SystemFmpPrivate- > >LastAttempt.LastAttemptStatus; > + ImageInfo->HardwareInstance =3D ImageDescriptor->HardwareIn= stance; > + > + // > + // package version > + // > + *PackageVersion =3D ImageDescriptor->PackageVersion; > + if (ImageDescriptor->PackageVersionNameStringOffset !=3D 0) { > + *PackageVersionName =3D (VOID *)((UINTN)ImageDescriptor + > ImageDescriptor->PackageVersionNameStringOffset); > + *PackageVersionName =3D AllocateCopyPool (StrSize > (*PackageVersionName), *PackageVersionName); > + } else { > + *PackageVersionName =3D NULL; > + } > + > + return EFI_SUCCESS; > +} > + > +/** > + Retrieves a copy of the current firmware image of the device. > + > + This function allows a copy of the current firmware image to be create= d and > saved. > + The saved copy could later been used, for example, in firmware image > recovery or rollback. > + > + @param[in] This A pointer to the > EFI_FIRMWARE_MANAGEMENT_PROTOCOL instance. > + @param[in] ImageIndex A unique number identifying the firmwar= e > image(s) within the device. > + The number is between 1 and DescriptorC= ount. > + @param[in,out] Image Points to the buffer where the current = image is > copied to. > + @param[in,out] ImageSize On entry, points to the size of the buf= fer > pointed to by Image, in bytes. > + On return, points to the length of the = image, in bytes. > + > + @retval EFI_SUCCESS The device was successfully updated wit= h the > new image. > + @retval EFI_BUFFER_TOO_SMALL The buffer specified by ImageSize is to= o > small to hold the > + image. The current buffer size needed t= o hold the image is > returned > + in ImageSize. > + @retval EFI_INVALID_PARAMETER The Image was NULL. > + @retval EFI_NOT_FOUND The current image is not copied to the = buffer. > + @retval EFI_UNSUPPORTED The operation is not supported. > + @retval EFI_SECURITY_VIOLATION The operation could not be performed > due to an authentication failure. > + > +**/ > +EFI_STATUS > +EFIAPI > +FmpGetImage ( > + IN EFI_FIRMWARE_MANAGEMENT_PROTOCOL *This, > + IN UINT8 ImageIndex, > + IN OUT VOID *Image, > + IN OUT UINTN *ImageSize > + ) > +{ > + return EFI_UNSUPPORTED; > +} > + > +/** > + Checks if the firmware image is valid for the device. > + > + This function allows firmware update application to validate the firmw= are > image without > + invoking the SetImage() first. > + > + @param[in] This A pointer to the > EFI_FIRMWARE_MANAGEMENT_PROTOCOL instance. > + @param[in] ImageIndex A unique number identifying the firmwar= e > image(s) within the device. > + The number is between 1 and DescriptorC= ount. > + @param[in] Image Points to the new image. > + @param[in] ImageSize Size of the new image in bytes. > + @param[out] ImageUpdatable Indicates if the new image is valid for > update. It also provides, > + if available, additional information if= the image is invalid. > + > + @retval EFI_SUCCESS The image was successfully checked. > + @retval EFI_INVALID_PARAMETER The Image was NULL. > + @retval EFI_UNSUPPORTED The operation is not supported. > + @retval EFI_SECURITY_VIOLATION The operation could not be performed > due to an authentication failure. > + > +**/ > +EFI_STATUS > +EFIAPI > +FmpCheckImage ( > + IN EFI_FIRMWARE_MANAGEMENT_PROTOCOL *This, > + IN UINT8 ImageIndex, > + IN CONST VOID *Image, > + IN UINTN ImageSize, > + OUT UINT32 *ImageUpdatable > + ) > +{ > + return EFI_UNSUPPORTED; > +} > + > +/** > + Returns information about the firmware package. > + > + This function returns package information. > + > + @param[in] This A pointer to the > EFI_FIRMWARE_MANAGEMENT_PROTOCOL instance. > + @param[out] PackageVersion A version number that represents = all the > firmware images in the device. > + The format is vendor specific and= new version must have > a greater value > + than the old version. If PackageV= ersion is not supported, > the value is > + 0xFFFFFFFF. A value of 0xFFFFFFFE= indicates that package > version > + comparison is to be performed usi= ng > PackageVersionName. A value of > + 0xFFFFFFFD indicates that package= version update is in > progress. > + @param[out] PackageVersionName A pointer to a pointer to a null- > terminated string representing > + the package version name. The buf= fer is allocated by this > function with > + AllocatePool(), and it is the cal= ler's responsibility to free it > with a > + call to FreePool(). > + @param[out] PackageVersionNameMaxLen The maximum length of > package version name if device supports update of > + package version name. A value of = 0 indicates the device > does not support > + update of package version name. L= ength is the number of > Unicode characters, > + including the terminating null ch= aracter. > + @param[out] AttributesSupported Package attributes that are suppo= rted > by this device. See 'Package Attribute > + Definitions' for possible returne= d values of this > parameter. A value of 1 > + indicates the attribute is suppor= ted and the current > setting value is > + indicated in AttributesSetting. A= value of 0 indicates the > attribute is not > + supported and the current setting= value in > AttributesSetting is meaningless. > + @param[out] AttributesSetting Package attributes. See 'Package > Attribute Definitions' for possible returned > + values of this parameter > + > + @retval EFI_SUCCESS The package information was succe= ssfully > returned. > + @retval EFI_UNSUPPORTED The operation is not supported. > + > +**/ > +EFI_STATUS > +EFIAPI > +FmpGetPackageInfo ( > + IN EFI_FIRMWARE_MANAGEMENT_PROTOCOL *This, > + OUT UINT32 *PackageVersion, > + OUT CHAR16 **PackageVersionName, > + OUT UINT32 *PackageVersionNameMaxLen, > + OUT UINT64 *AttributesSupported, > + OUT UINT64 *AttributesSetting > + ) > +{ > + return EFI_UNSUPPORTED; > +} > + > +/** > + Updates information about the firmware package. > + > + This function updates package information. > + This function returns EFI_UNSUPPORTED if the package information is no= t > updatable. > + VendorCode enables vendor to implement vendor-specific package > information update policy. > + Null if the caller did not specify this policy or use the default poli= cy. > + > + @param[in] This A pointer to the > EFI_FIRMWARE_MANAGEMENT_PROTOCOL instance. > + @param[in] Image Points to the authentication image. > + Null if authentication is not required. > + @param[in] ImageSize Size of the authentication image in byt= es. > + 0 if authentication is not required. > + @param[in] VendorCode This enables vendor to implement vendor= - > specific firmware > + image update policy. > + Null indicates the caller did not speci= fy this policy or use > + the default policy. > + @param[in] PackageVersion The new package version. > + @param[in] PackageVersionName A pointer to the new null-terminated > Unicode string representing > + the package version name. > + The string length is equal to or less t= han the value returned in > + PackageVersionNameMaxLen. > + > + @retval EFI_SUCCESS The device was successfully updated wit= h the > new package > + information. > + @retval EFI_INVALID_PARAMETER The PackageVersionName length is > longer than the value > + returned in PackageVersionNameMaxLen. > + @retval EFI_UNSUPPORTED The operation is not supported. > + @retval EFI_SECURITY_VIOLATION The operation could not be performed > due to an authentication failure. > + > +**/ > +EFI_STATUS > +EFIAPI > +FmpSetPackageInfo ( > + IN EFI_FIRMWARE_MANAGEMENT_PROTOCOL *This, > + IN CONST VOID *Image, > + IN UINTN ImageSize, > + IN CONST VOID *VendorCode, > + IN UINT32 PackageVersion, > + IN CONST CHAR16 *PackageVersionName > + ) > +{ > + return EFI_UNSUPPORTED; > +} > + > +/** > + Initialize SystemFmpDriver private data structure. > + > + @param[in] SystemFmpPrivate private data structure to be initialized. > + > + @return EFI_SUCCESS private data is initialized. > +**/ > +EFI_STATUS > +InitializePrivateData ( > + IN SYSTEM_FMP_PRIVATE_DATA *SystemFmpPrivate > + ) > +{ > + EFI_STATUS VarStatus; > + UINTN VarSize; > + > + SystemFmpPrivate->Signature =3D > SYSTEM_FMP_PRIVATE_DATA_SIGNATURE; > + SystemFmpPrivate->Handle =3D NULL; > + SystemFmpPrivate->DescriptorCount =3D 1; > + CopyMem (&SystemFmpPrivate->Fmp, &mFirmwareManagementProtocol, > sizeof (EFI_FIRMWARE_MANAGEMENT_PROTOCOL)); > + > + SystemFmpPrivate->ImageDescriptor =3D PcdGetPtr > (PcdEdkiiSystemFirmwareImageDescriptor); > + > + SystemFmpPrivate->LastAttempt.LastAttemptVersion =3D 0x0; > + SystemFmpPrivate->LastAttempt.LastAttemptStatus =3D 0x0; > + VarSize =3D sizeof (SystemFmp= Private->LastAttempt); > + VarStatus =3D gRT->GetVariable = ( > + > SYSTEM_FMP_LAST_ATTEMPT_VARIABLE_NAME, > + &gSystemFmpL= astAttemptVariableGuid, > + NULL, > + &VarSize, > + &SystemFmpPr= ivate->LastAttempt > + ); > + DEBUG ((DEBUG_INFO, "GetLastAttemp - %r\n", VarStatus)); > + DEBUG ((DEBUG_INFO, "GetLastAttemp Version - 0x%x, State - 0x%x\n", > SystemFmpPrivate->LastAttempt.LastAttemptVersion, SystemFmpPrivate- > >LastAttempt.LastAttemptStatus)); > + > + return EFI_SUCCESS; > +} > + > +/** > + Return if this FMP is a system FMP or a device FMP, based upon > FmpImageInfo. > + > + @param[in] FmpImageInfo A pointer to > EFI_FIRMWARE_IMAGE_DESCRIPTOR > + > + @retval TRUE It is a system FMP. > + @retval FALSE It is a device FMP. > +**/ > +BOOLEAN > +IsSystemFmp ( > + IN EFI_FIRMWARE_IMAGE_DESCRIPTOR *FmpImageInfo > + ) > +{ > + GUID *Guid; > + UINTN Count; > + UINTN Index; > + > + Guid =3D PcdGetPtr (PcdSystemFmpCapsuleImageTypeIdGuid); > + Count =3D PcdGetSize (PcdSystemFmpCapsuleImageTypeIdGuid) / sizeof > (GUID); > + > + for (Index =3D 0; Index < Count; Index++, Guid++) { > + if (CompareGuid (&FmpImageInfo->ImageTypeId, Guid)) { > + return TRUE; > + } > + } > + > + return FALSE; > +} > diff --git > a/Platform/AMD/VanGoghBoard/Override/edk2/SignedCapsulePkg/Universal > /SystemFirmwareUpdate/SystemFirmwareDxe.h > b/Platform/AMD/VanGoghBoard/Override/edk2/SignedCapsulePkg/Universa > l/SystemFirmwareUpdate/SystemFirmwareDxe.h > new file mode 100644 > index 0000000000..b1aab4c41e > --- /dev/null > +++ > b/Platform/AMD/VanGoghBoard/Override/edk2/SignedCapsulePkg/Universa > l/SystemFirmwareUpdate/SystemFirmwareDxe.h > @@ -0,0 +1,421 @@ > +/** @file > + System Firmware update header file. > + > + Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved. > + Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.
> + SPDX-License-Identifier: BSD-2-Clause-Patent > + > +**/ > + > +#ifndef SYSTEM_FIRMWARE_UPDATE_H__ > +#define SYSTEM_FIRMWARE_UPDATE_H__ > + > +#include > + > +#include > +#include > +#include > +#include > + > +#include > +#include > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +typedef struct { > + UINT32 LastAttemptVersion; > + UINT32 LastAttemptStatus; > +} SYSTEM_FMP_LAST_ATTEMPT_VARIABLE; > + > +#define SYSTEM_FMP_LAST_ATTEMPT_VARIABLE_NAME > L"SystemLastAttempVar" > + > +#define SYSTEM_FMP_LAST_ATTEMPT_VARIABLE_GUID {0x2f564d6f, > 0xcc2c, 0x4838, { 0xb9, 0xa8, 0xbe, 0x59, 0x48, 0xb0, 0x3d, 0x59 }} > + > +#define SYSTEM_FMP_PRIVATE_DATA_SIGNATURE SIGNATURE_32('S', 'Y', > 'S', 'F') > + > +#define SYSTEM_FMP_PROTOCOL_GUID {0x6d16624a, 0x26a6, 0x4cb4, > { 0x84, 0xfa, 0x6, 0x78, 0x5a, 0x7e, 0x82, 0x6a }} > + > +// > +// SYSTEM FMP private data structure. > +// > + > +struct _SYSTEM_FMP_PRIVATE_DATA { > + UINT32 Signature; > + EFI_FIRMWARE_MANAGEMENT_PROTOCOL Fmp; > + EFI_HANDLE Handle; > + UINT8 DescriptorCount; > + EDKII_SYSTEM_FIRMWARE_IMAGE_DESCRIPTOR *ImageDescriptor; > + SYSTEM_FMP_LAST_ATTEMPT_VARIABLE LastAttempt; > +}; > + > +typedef struct _SYSTEM_FMP_PRIVATE_DATA SYSTEM_FMP_PRIVATE_DATA; > + > +/** > + Returns a pointer to the SYSTEM_FMP_PRIVATE_DATA structure from the > input a as Fmp. > + > + If the signatures matches, then a pointer to the data structure that c= ontains > + a specified field of that data structure is returned. > + > + @param a Pointer to the field specified by ServiceBindin= g within > + a data structure of type SYSTEM_FMP_PRIVATE_DAT= A. > + > +**/ > +#define SYSTEM_FMP_PRIVATE_DATA_FROM_FMP(a) \ > + CR ( \ > + (a), \ > + SYSTEM_FMP_PRIVATE_DATA, \ > + Fmp, \ > + SYSTEM_FMP_PRIVATE_DATA_SIGNATURE \ > + ) > + > +// > +// Update data > +// > + > +typedef struct { > + UINTN NumOfUpdates; > +} CONFIG_HEADER; > + > +typedef struct { > + UINTN Index; > + PLATFORM_FIRMWARE_TYPE FirmwareType; > + FLASH_ADDRESS_TYPE AddressType; > + EFI_GUID FileGuid; > + EFI_PHYSICAL_ADDRESS BaseAddress; > + UINTN Length; > + UINTN ImageOffset; > +} UPDATE_CONFIG_DATA; > + > +// > +// System Firmware Update SMM Communication > +// > + > +#define > SYSTEM_FIRMWARE_UPDATE_COMMUNICATION_FUNCTION_SET_IMAGE 1 > + > +typedef struct { > + UINTN Function; > + EFI_STATUS ReturnStatus; > + // UINT8 Data[]; > +} SYSTEM_FIRMWARE_UPDATE_COMMUNICATION_HEAD; > + > +#define ABORT_REASON_MAX_SIZE 0x40 // UnicodeStringSize > including final L'\0' > + > +#define CAPSULE_IMAGE_ADDITIONAL_MAX_SIZE (0x20020 + 0xA0000) // > Addtional size for Capsule Header, FV block alignment + DispatchImage. > + > +typedef struct { > + UINT8 ImageIndex; > + UINTN ImageSize; > + UINTN AbortReasonSize; > + UINT32 LastAttemptVersion; > + UINT32 LastAttemptStatus; > + // UINT8 Data[AbortReasonMaxSize + ImageSize]; > +} SYSTEM_FIRMWARE_UPDATE_COMMUNICATION_SET_IMAGE; > + > +/* > +Name Offset(byte) Size(byte) Comments > +SlotA_Priority 0x0 4 Read and Write the Slot = A priority > +SlotA_UpdateRetries 0x4 4 Read and Write the Slot = A retries > +SlotA_GlitchRetries 0x8 4 Read only, Slot A glitch > +SlotB_Priority 0xC 4 Read and Write the Slot = B priority > +SlotB_UpdateRetries 0x10 4 Read and Write the Slot = B retries > +SlotB_GlitchRetries 0x14 4 Read only, Slot B glitch > + > +*/ > +typedef struct { > + UINT32 SlotA_Priority; > + UINT32 SlotA_UpdateRetries; > + UINT32 SlotA_GlitchRetries; > + UINT32 SlotB_Priority; > + UINT32 SlotB_UpdateRetries; > + UINT32 SlotB_GlitchRetries; > +} IMAGE_SLOT_HEADER_INFO; > + > +/** > + Returns information about the current firmware image(s) of the device. > + > + This function allows a copy of the current firmware image to be create= d and > saved. > + The saved copy could later been used, for example, in firmware image > recovery or rollback. > + > + @param[in] This A pointer to the > EFI_FIRMWARE_MANAGEMENT_PROTOCOL instance. > + @param[in, out] ImageInfoSize A pointer to the size, in bytes, of= the > ImageInfo buffer. > + On input, this is the size of the b= uffer allocated by the > caller. > + On output, it is the size of the bu= ffer returned by the > firmware > + if the buffer was large enough, or = the size of the buffer > needed > + to contain the image(s) information= if the buffer was too > small. > + @param[in, out] ImageInfo A pointer to the buffer in which fi= rmware > places the current image(s) > + information. The information is an = array of > EFI_FIRMWARE_IMAGE_DESCRIPTORs. > + @param[out] DescriptorVersion A pointer to the location in which > firmware returns the version number > + associated with the EFI_FIRMWARE_IM= AGE_DESCRIPTOR. > + @param[out] DescriptorCount A pointer to the location in which > firmware returns the number of > + descriptors or firmware images with= in this device. > + @param[out] DescriptorSize A pointer to the location in which = firmware > returns the size, in bytes, > + of an individual EFI_FIRMWARE_IMAGE= _DESCRIPTOR. > + @param[out] PackageVersion A version number that represents al= l the > firmware images in the device. > + The format is vendor specific and n= ew version must have a > greater value > + than the old version. If PackageVer= sion is not supported, > the value is > + 0xFFFFFFFF. A value of 0xFFFFFFFE i= ndicates that package > version comparison > + is to be performed using PackageVer= sionName. A value of > 0xFFFFFFFD indicates > + that package version update is in p= rogress. > + @param[out] PackageVersionName A pointer to a pointer to a null- > terminated string representing the > + package version name. The buffer is= allocated by this > function with > + AllocatePool(), and it is the calle= r's responsibility to free it > with a call > + to FreePool(). > + > + @retval EFI_SUCCESS The device was successfully updated= with the > new image. > + @retval EFI_BUFFER_TOO_SMALL The ImageInfo buffer was too small. > The current buffer size > + needed to hold the image(s) informa= tion is returned in > ImageInfoSize. > + @retval EFI_INVALID_PARAMETER ImageInfoSize is NULL. > + @retval EFI_DEVICE_ERROR Valid information could not be retu= rned. > Possible corrupted image. > + > +**/ > +EFI_STATUS > +EFIAPI > +FmpGetImageInfo ( > + IN EFI_FIRMWARE_MANAGEMENT_PROTOCOL *This, > + IN OUT UINTN *ImageInfoSize, > + IN OUT EFI_FIRMWARE_IMAGE_DESCRIPTOR *ImageInfo, > + OUT UINT32 *DescriptorVersion, > + OUT UINT8 *DescriptorCount, > + OUT UINTN *DescriptorSize, > + OUT UINT32 *PackageVersion, > + OUT CHAR16 **PackageVersionName > + ); > + > +/** > + Retrieves a copy of the current firmware image of the device. > + > + This function allows a copy of the current firmware image to be create= d and > saved. > + The saved copy could later been used, for example, in firmware image > recovery or rollback. > + > + @param[in] This A pointer to the > EFI_FIRMWARE_MANAGEMENT_PROTOCOL instance. > + @param[in] ImageIndex A unique number identifying the firmwar= e > image(s) within the device. > + The number is between 1 and DescriptorC= ount. > + @param[in,out] Image Points to the buffer where the current = image is > copied to. > + @param[in,out] ImageSize On entry, points to the size of the buf= fer > pointed to by Image, in bytes. > + On return, points to the length of the = image, in bytes. > + > + @retval EFI_SUCCESS The device was successfully updated wit= h the > new image. > + @retval EFI_BUFFER_TOO_SMALL The buffer specified by ImageSize is to= o > small to hold the > + image. The current buffer size needed t= o hold the image is > returned > + in ImageSize. > + @retval EFI_INVALID_PARAMETER The Image was NULL. > + @retval EFI_NOT_FOUND The current image is not copied to the = buffer. > + @retval EFI_UNSUPPORTED The operation is not supported. > + @retval EFI_SECURITY_VIOLATION The operation could not be performed > due to an authentication failure. > + > +**/ > +EFI_STATUS > +EFIAPI > +FmpGetImage ( > + IN EFI_FIRMWARE_MANAGEMENT_PROTOCOL *This, > + IN UINT8 ImageIndex, > + IN OUT VOID *Image, > + IN OUT UINTN *ImageSize > + ); > + > +/** > + Updates the firmware image of the device. > + > + This function updates the hardware with the new firmware image. > + This function returns EFI_UNSUPPORTED if the firmware image is not > updatable. > + If the firmware image is updatable, the function should perform the > following minimal validations > + before proceeding to do the firmware image update. > + - Validate the image authentication if image has attribute > + IMAGE_ATTRIBUTE_AUTHENTICATION_REQUIRED. The function returns > + EFI_SECURITY_VIOLATION if the validation fails. > + - Validate the image is a supported image for this device. The functio= n > returns EFI_ABORTED if > + the image is unsupported. The function can optionally provide more > detailed information on > + why the image is not a supported image. > + - Validate the data from VendorCode if not null. Image validation must= be > performed before > + VendorCode data validation. VendorCode data is ignored or considered > invalid if image > + validation failed. The function returns EFI_ABORTED if the data is i= nvalid. > + > + VendorCode enables vendor to implement vendor-specific firmware image > update policy. Null if > + the caller did not specify the policy or use the default policy. As an= example, > vendor can implement > + a policy to allow an option to force a firmware image update when the = abort > reason is due to the new > + firmware image version is older than the current firmware image versio= n or > bad image checksum. > + Sensitive operations such as those wiping the entire firmware image an= d > render the device to be > + non-functional should be encoded in the image itself rather than passe= d > with the VendorCode. > + AbortReason enables vendor to have the option to provide a more detail= ed > description of the abort > + reason to the caller. > + > + @param[in] This A pointer to the > EFI_FIRMWARE_MANAGEMENT_PROTOCOL instance. > + @param[in] ImageIndex A unique number identifying the firmwar= e > image(s) within the device. > + The number is between 1 and DescriptorC= ount. > + @param[in] Image Points to the new image. > + @param[in] ImageSize Size of the new image in bytes. > + @param[in] VendorCode This enables vendor to implement vendor= - > specific firmware image update policy. > + Null indicates the caller did not speci= fy the policy or use the > default policy. > + @param[in] Progress A function used by the driver to report= the > progress of the firmware update. > + @param[out] AbortReason A pointer to a pointer to a null-termin= ated > string providing more > + details for the aborted operation. The = buffer is allocated by > this function > + with AllocatePool(), and it is the call= er's responsibility to free > it with a > + call to FreePool(). > + > + @retval EFI_SUCCESS The device was successfully updated wit= h the > new image. > + @retval EFI_ABORTED The operation is aborted. > + @retval EFI_INVALID_PARAMETER The Image was NULL. > + @retval EFI_UNSUPPORTED The operation is not supported. > + @retval EFI_SECURITY_VIOLATION The operation could not be performed > due to an authentication failure. > + > +**/ > +EFI_STATUS > +EFIAPI > +FmpSetImage ( > + IN EFI_FIRMWARE_MANAGEMENT_PROTOCOL *This, > + IN UINT8 ImageIndex, > + IN CONST VOID *Image, > + IN UINTN ImageSize, > + IN CONST VOID *VendorCode, > + IN EFI_FIRMWARE_MANAGEMENT_UPDATE_IMAGE_PROGRESS Progress, > + OUT CHAR16 **AbortReason > + ); > + > +/** > + Checks if the firmware image is valid for the device. > + > + This function allows firmware update application to validate the firmw= are > image without > + invoking the SetImage() first. > + > + @param[in] This A pointer to the > EFI_FIRMWARE_MANAGEMENT_PROTOCOL instance. > + @param[in] ImageIndex A unique number identifying the firmwar= e > image(s) within the device. > + The number is between 1 and DescriptorC= ount. > + @param[in] Image Points to the new image. > + @param[in] ImageSize Size of the new image in bytes. > + @param[out] ImageUpdatable Indicates if the new image is valid for > update. It also provides, > + if available, additional information if= the image is invalid. > + > + @retval EFI_SUCCESS The image was successfully checked. > + @retval EFI_INVALID_PARAMETER The Image was NULL. > + @retval EFI_UNSUPPORTED The operation is not supported. > + @retval EFI_SECURITY_VIOLATION The operation could not be performed > due to an authentication failure. > + > +**/ > +EFI_STATUS > +EFIAPI > +FmpCheckImage ( > + IN EFI_FIRMWARE_MANAGEMENT_PROTOCOL *This, > + IN UINT8 ImageIndex, > + IN CONST VOID *Image, > + IN UINTN ImageSize, > + OUT UINT32 *ImageUpdatable > + ); > + > +/** > + Returns information about the firmware package. > + > + This function returns package information. > + > + @param[in] This A pointer to the > EFI_FIRMWARE_MANAGEMENT_PROTOCOL instance. > + @param[out] PackageVersion A version number that represents = all the > firmware images in the device. > + The format is vendor specific and= new version must have > a greater value > + than the old version. If PackageV= ersion is not supported, > the value is > + 0xFFFFFFFF. A value of 0xFFFFFFFE= indicates that package > version > + comparison is to be performed usi= ng > PackageVersionName. A value of > + 0xFFFFFFFD indicates that package= version update is in > progress. > + @param[out] PackageVersionName A pointer to a pointer to a null- > terminated string representing > + the package version name. The buf= fer is allocated by this > function with > + AllocatePool(), and it is the cal= ler's responsibility to free it > with a > + call to FreePool(). > + @param[out] PackageVersionNameMaxLen The maximum length of > package version name if device supports update of > + package version name. A value of = 0 indicates the device > does not support > + update of package version name. L= ength is the number of > Unicode characters, > + including the terminating null ch= aracter. > + @param[out] AttributesSupported Package attributes that are suppo= rted > by this device. See 'Package Attribute > + Definitions' for possible returne= d values of this > parameter. A value of 1 > + indicates the attribute is suppor= ted and the current > setting value is > + indicated in AttributesSetting. A= value of 0 indicates the > attribute is not > + supported and the current setting= value in > AttributesSetting is meaningless. > + @param[out] AttributesSetting Package attributes. See 'Package > Attribute Definitions' for possible returned > + values of this parameter > + > + @retval EFI_SUCCESS The package information was succe= ssfully > returned. > + @retval EFI_UNSUPPORTED The operation is not supported. > + > +**/ > +EFI_STATUS > +EFIAPI > +FmpGetPackageInfo ( > + IN EFI_FIRMWARE_MANAGEMENT_PROTOCOL *This, > + OUT UINT32 *PackageVersion, > + OUT CHAR16 **PackageVersionName, > + OUT UINT32 *PackageVersionNameMaxLen, > + OUT UINT64 *AttributesSupported, > + OUT UINT64 *AttributesSetting > + ); > + > +/** > + Updates information about the firmware package. > + > + This function updates package information. > + This function returns EFI_UNSUPPORTED if the package information is no= t > updatable. > + VendorCode enables vendor to implement vendor-specific package > information update policy. > + Null if the caller did not specify this policy or use the default poli= cy. > + > + @param[in] This A pointer to the > EFI_FIRMWARE_MANAGEMENT_PROTOCOL instance. > + @param[in] Image Points to the authentication image. > + Null if authentication is not required. > + @param[in] ImageSize Size of the authentication image in byt= es. > + 0 if authentication is not required. > + @param[in] VendorCode This enables vendor to implement vendor= - > specific firmware > + image update policy. > + Null indicates the caller did not speci= fy this policy or use > + the default policy. > + @param[in] PackageVersion The new package version. > + @param[in] PackageVersionName A pointer to the new null-terminated > Unicode string representing > + the package version name. > + The string length is equal to or less t= han the value returned in > + PackageVersionNameMaxLen. > + > + @retval EFI_SUCCESS The device was successfully updated wit= h the > new package > + information. > + @retval EFI_INVALID_PARAMETER The PackageVersionName length is > longer than the value > + returned in PackageVersionNameMaxLen. > + @retval EFI_UNSUPPORTED The operation is not supported. > + @retval EFI_SECURITY_VIOLATION The operation could not be performed > due to an authentication failure. > + > +**/ > +EFI_STATUS > +EFIAPI > +FmpSetPackageInfo ( > + IN EFI_FIRMWARE_MANAGEMENT_PROTOCOL *This, > + IN CONST VOID *Image, > + IN UINTN ImageSize, > + IN CONST VOID *VendorCode, > + IN UINT32 PackageVersion, > + IN CONST CHAR16 *PackageVersionName > + ); > + > +/** > + Initialize SystemFmpDriver private data structure. > + > + @param[in] SystemFmpPrivate private data structure to be initialized. > + > + @return EFI_SUCCESS private data is initialized. > +**/ > +EFI_STATUS > +InitializePrivateData ( > + IN SYSTEM_FMP_PRIVATE_DATA *SystemFmpPrivate > + ); > + > +extern EFI_GUID gSystemFmpLastAttemptVariableGuid; > +extern EFI_GUID mCurrentImageTypeId; > +extern EFI_GUID gSystemFmpProtocolGuid; > + > +#endif > diff --git > a/Platform/AMD/VanGoghBoard/Override/edk2/SignedCapsulePkg/Universal > /SystemFirmwareUpdate/SystemFirmwareUpdateDxe.c > b/Platform/AMD/VanGoghBoard/Override/edk2/SignedCapsulePkg/Universa > l/SystemFirmwareUpdate/SystemFirmwareUpdateDxe.c > new file mode 100644 > index 0000000000..894d363de0 > --- /dev/null > +++ > b/Platform/AMD/VanGoghBoard/Override/edk2/SignedCapsulePkg/Universa > l/SystemFirmwareUpdate/SystemFirmwareUpdateDxe.c > @@ -0,0 +1,1426 @@ > +/** @file > + SetImage instance to update system firmware. > + > + Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved. > + Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.
> + SPDX-License-Identifier: BSD-2-Clause-Patent > + > +**/ > + > +#include "SystemFirmwareDxe.h" > + > +// > +// SystemFmp driver private data > +// > +SYSTEM_FMP_PRIVATE_DATA *mSystemFmpPrivate =3D NULL; > + > +EFI_GUID mCurrentImageTypeId; > + > +BOOLEAN mNvRamUpdated =3D FALSE; > + > +UINT8 mUpdateSlot =3D 0; > + > +/** > + Parse Config data file to get the updated data array. > + > + @param[in] DataBuffer Config raw file buffer. > + @param[in] BufferSize Size of raw buffer. > + @param[in, out] ConfigHeader Pointer to the config header. > + @param[in, out] UpdateArray Pointer to the config of update data. > + > + @retval EFI_NOT_FOUND No config data is found. > + @retval EFI_OUT_OF_RESOURCES No enough memory is allocated. > + @retval EFI_SUCCESS Parse the config file successfully. > + > +**/ > +EFI_STATUS > +ParseUpdateDataFile ( > + IN UINT8 *DataBuffer, > + IN UINTN BufferSize, > + IN OUT CONFIG_HEADER *ConfigHeader, > + IN OUT UPDATE_CONFIG_DATA **UpdateArray > + ); > + > +/** > + Update System Firmware image component. > + > + @param[in] SystemFirmwareImage Points to the System Firmware > image. > + @param[in] SystemFirmwareImageSize The length of the System Firmware > image in bytes. > + @param[in] ConfigData Points to the component configurat= ion > structure. > + @param[out] LastAttemptVersion The last attempt version, which wi= ll be > recorded in ESRT and FMP EFI_FIRMWARE_IMAGE_DESCRIPTOR. > + @param[out] LastAttemptStatus The last attempt status, which wil= l be > recorded in ESRT and FMP EFI_FIRMWARE_IMAGE_DESCRIPTOR. > + @param[in] Progress A function used by the driver to r= eport the > progress of the firmware update. > + @param[in] StartPercentage The start completion percentage va= lue > that may be used to report progress during the flash write operation. > + @param[in] EndPercentage The end completion percentage valu= e that > may be used to report progress during the flash write operation. > + > + @retval EFI_SUCCESS The System Firmware image is updated. > + @retval EFI_WRITE_PROTECTED The flash device is read only. > +**/ > +EFI_STATUS > +PerformUpdate ( > + IN VOID *SystemFirmwareImage= , > + IN UINTN SystemFirmwareImageS= ize, > + IN UPDATE_CONFIG_DATA *ConfigData, > + OUT UINT32 *LastAttemptVersion, > + OUT UINT32 *LastAttemptStatus, > + IN EFI_FIRMWARE_MANAGEMENT_UPDATE_IMAGE_PROGRESS Progress, > + IN UINTN StartPercentage, > + IN UINTN EndPercentage > + ) > +{ > + EFI_STATUS Status; > + > + DEBUG ((DEBUG_INFO, "PlatformUpdate:")); > + DEBUG ((DEBUG_INFO, " BaseAddress - 0x%lx,", ConfigData- > >BaseAddress)); > + DEBUG ((DEBUG_INFO, " ImageOffset - 0x%x,", ConfigData->ImageOffset))= ; > + DEBUG ((DEBUG_INFO, " Legnth - 0x%x\n", ConfigData->Length)); > + if (Progress !=3D NULL) { > + Progress (StartPercentage); > + } > + > + Status =3D PerformFlashWriteWithProgress ( > + ConfigData->FirmwareType, > + ConfigData->BaseAddress, > + ConfigData->AddressType, > + (VOID *)((UINTN)SystemFirmwareImage + (UINTN)ConfigData- > >ImageOffset), > + ConfigData->Length, > + Progress, > + StartPercentage, > + EndPercentage > + ); > + if (Progress !=3D NULL) { > + Progress (EndPercentage); > + } > + > + if (!EFI_ERROR (Status)) { > + *LastAttemptStatus =3D LAST_ATTEMPT_STATUS_SUCCESS; > + if (ConfigData->FirmwareType =3D=3D PlatformFirmwareTypeNvRam) { > + mNvRamUpdated =3D TRUE; > + } > + } else { > + *LastAttemptStatus =3D LAST_ATTEMPT_STATUS_ERROR_UNSUCCESSFUL; > + } > + > + return Status; > +} > + > +/** > + Get layout of system firmware image. > + > + @param[in] SystemFirmwareImage Points to the System firmware imag= e. > + @param[out] SlotAOffset Points to the offste of slot A ima= ge. > + @param[out] SlotBOffset Points to the offste of slot B ima= ge. > + > + @retval EFI_SUCCESS Get system firmware image layout > successfully. > + @retval others Some error occurs when executing t= his routine. > + > +**/ > +EFI_STATUS > +GetImageLayout ( > + IN VOID *SystemFirmwareImage, > + OUT UINT32 *SlotAOffset, > + OUT UINT32 *SlotBOffset, > + OUT UINT8 *ActiveSlot > + ) > +{ > + FIRMWARE_ENTRY_TABLEV2 *EfsAddressPtr; > + PSP_DIRECTORY *PspL1DirectoryPtr; > + UINT32 SlotCount; > + UINT32 Index; > + IMAGE_SLOT_HEADER *IshSlotAInfoPtr; > + IMAGE_SLOT_HEADER *IshSlotBInfoPtr; > + > + if (SystemFirmwareImage =3D=3D NULL) { > + return EFI_INVALID_PARAMETER; > + } > + > + if ((SlotAOffset =3D=3D NULL) || (SlotBOffset =3D=3D NULL)) { > + return EFI_INVALID_PARAMETER; > + } > + > + // > + // Check EFS structure of firmware image > + // > + EfsAddressPtr =3D (FIRMWARE_ENTRY_TABLEV2 *)(UINTN)((UINT8 > *)SystemFirmwareImage + EFS_LOCATION); > + if (EfsAddressPtr->Signature !=3D FIRMWARE_TABLE_SIGNATURE) { > + DEBUG ((DEBUG_ERROR, "EFS signature incorrect.\n")); > + return EFI_NOT_FOUND; > + } > + > + // > + // Check PSP_L1_DIRECTORY of firmware image > + // > + DEBUG ((DEBUG_INFO, "Base Address for PSP directory: 0x%x\n", > EfsAddressPtr->PspDirBase)); > + PspL1DirectoryPtr =3D (PSP_DIRECTORY *)(UINTN)((UINT8 > *)SystemFirmwareImage + EfsAddressPtr->PspDirBase); > + if ((PspL1DirectoryPtr->Header.Cookie !=3D > PSP_DIRECTORY_HEADER_SIGNATURE) || > + (!IS_VALID_ADDR32 (EfsAddressPtr->PspDirBase)) || > + (!ALIGN_4K_CHECK (EfsAddressPtr->PspDirBase)) || > + (PspL1DirectoryPtr->Header.TotalEntries =3D=3D 0) || > + (PspL1DirectoryPtr->Header.TotalEntries > MAX_IMAGE_SLOT_COUNT) > + ) > + { > + DEBUG ((DEBUG_ERROR, "PSP L1 directory address, slot count or signat= ure > error!\n")); > + return EFI_NOT_FOUND; > + } > + > + // > + // Check Image Slot entries of firmware image > + // > + SlotCount =3D PspL1DirectoryPtr->Header.TotalEntries; > + for (Index =3D 0; Index < SlotCount; Index++) { > + if (((PspL1DirectoryPtr->PspEntry[Index].Type.Value !=3D > PSP_REGION_A_DIR) && > + (PspL1DirectoryPtr->PspEntry[Index].Type.Value !=3D > PSP_REGION_B_DIR)) || > + (!IS_VALID_ADDR32 (PspL1DirectoryPtr->PspEntry[Index].Location))= || > + (!ALIGN_4K_CHECK (PspL1DirectoryPtr->PspEntry[Index].Location)) = || > + (((PspL1DirectoryPtr->PspEntry[Index].Location) & > 0xFFFFFFFF00000000) !=3D 0) > + ) > + { > + DEBUG ((DEBUG_ERROR, "PSP L1 directory slot %d data error!\n", > Index)); > + return EFI_NOT_FOUND; > + } > + } > + > + // > + // Get offset of specific slot > + // > + IshSlotAInfoPtr =3D (IMAGE_SLOT_HEADER *)(UINTN)((UINT8 > *)SystemFirmwareImage + PspL1DirectoryPtr->PspEntry[0].Location); > + *SlotAOffset =3D IshSlotAInfoPtr->ImageSlotAddr; > + DEBUG ((DEBUG_ERROR, "Slot A image offset: 0x%x\n", *SlotAOffset)); > + > + IshSlotBInfoPtr =3D (IMAGE_SLOT_HEADER *)(UINTN)((UINT8 > *)SystemFirmwareImage + PspL1DirectoryPtr->PspEntry[1].Location); > + *SlotBOffset =3D IshSlotBInfoPtr->ImageSlotAddr; > + DEBUG ((DEBUG_ERROR, "Slot B image offset: 0x%x\n", *SlotBOffset)); > + > + if ((*SlotAOffset =3D=3D 0) || (*SlotBOffset =3D=3D 0)) { > + return EFI_NOT_FOUND; > + } > + > + if (ActiveSlot !=3D NULL) { > + if (IshSlotAInfoPtr->Priority > IshSlotBInfoPtr->Priority) { > + *ActiveSlot =3D SLOT_A; > + } else { > + *ActiveSlot =3D SLOT_B; > + } > + } > + > + return EFI_SUCCESS; > +} > + > +/** > + Verify layout of OTA Capsule firmware image, and return offset and siz= e of > required update slot. > + > + @param[in] SystemFirmwareImage Points to the System firmware imag= e. > + @param[in] UpdateSlot The slot number need to be updated= . > + @param[out] UpdateOffset The firmware image offset need to > updated. > + @param[out] UpdateSize The firmware image size need to up= dated. > + > + @retval EFI_SUCCESS Verify OTA capsule image and get u= pdated > offset/size successfully. > + @retval others Some error occurs when executing t= his routine. > + > +**/ > +EFI_STATUS > +VerifyImageLayout ( > + IN VOID *SystemFirmwareImage, > + IN UINT8 UpdateSlot, > + OUT UINT32 *UpdateOffset, > + OUT UINT32 *UpdateSize > + ) > +{ > + EFI_STATUS Status; > + UINT32 OtaSlotAOffset; > + UINT32 OtaSlotBOffset; > + UINT32 FlashSlotAOffset; > + UINT32 FlashSlotBOffset; > + UINT8 CurrentActiveSlot; > + > + if (SystemFirmwareImage =3D=3D NULL) { > + return EFI_INVALID_PARAMETER; > + } > + > + if ((UpdateOffset =3D=3D NULL) || (UpdateSize =3D=3D NULL)) { > + return EFI_INVALID_PARAMETER; > + } > + > + OtaSlotAOffset =3D 0; > + OtaSlotBOffset =3D 0; > + FlashSlotAOffset =3D 0; > + FlashSlotBOffset =3D 0; > + > + // > + // Get image layout of OTA Capsule > + // > + DEBUG ((DEBUG_INFO, "Get image layout of OTA Capsule.\n")); > + Status =3D GetImageLayout (SystemFirmwareImage, &OtaSlotAOffset, > &OtaSlotBOffset, NULL); > + if (EFI_ERROR (Status)) { > + DEBUG ((DEBUG_ERROR, "GetImageLayout of Capsule failed: %r\n", > Status)); > + return Status; > + } > + > + // > + // Get image layout of firmware in flash ROM > + // > + DEBUG ((DEBUG_INFO, "Get image layout of flash ROM.\n")); > + Status =3D GetImageLayout ((VOID *)(UINTN)(PcdGet32 > (PcdFlashAreaBaseAddress)), &FlashSlotAOffset, &FlashSlotBOffset, > &CurrentActiveSlot); > + if (EFI_ERROR (Status)) { > + DEBUG ((DEBUG_ERROR, "GetImageLayout of Flash failed: %r\n", Status)= ); > + return Status; > + } > + > + // > + // Check current active slot and update slot > + // > + // - if (CurrentActiveSlot =3D=3D mUpdateSlot) { > + // - DEBUG ((DEBUG_ERROR, "Can't update Capsule on current active sl= ot. > CurrentActiveSlot: %d, UpdateSlot: %d\n", CurrentActiveSlot, mUpdateSlot)= ); > + // - return EFI_INVALID_PARAMETER; > + // - } > + // > + // Compare layout of OTA capsule image and flash firmware > + // > + if ((OtaSlotAOffset !=3D FlashSlotAOffset) || (OtaSlotBOffset !=3D > FlashSlotBOffset)) { > + DEBUG ((DEBUG_ERROR, "Layout is different between Capsule and > Flash.\n")); > + return EFI_NOT_FOUND; > + } > + > + if (UpdateSlot =3D=3D SLOT_A) { > + *UpdateOffset =3D OtaSlotAOffset; > + } else if (UpdateSlot =3D=3D SLOT_B) { > + *UpdateOffset =3D OtaSlotBOffset; > + } else { > + DEBUG ((DEBUG_ERROR, "Invalid update slot number: %d\n", > UpdateSlot)); > + return EFI_INVALID_PARAMETER; > + } > + > + // - *UpdateSize =3D (UINT32) DivU64x64Remainder ((UINTN) PcdGet32 > (PcdFlashAreaSize) - OtaSlotAOffset, 2, NULL); > + *UpdateSize =3D (UINT32)((UINTN)PcdGet32 (PcdFlashAreaSize) - > OtaSlotAOffset); > + > + return EFI_SUCCESS; > +} > + > +/** > + Get OTA Capsule firmware image info. > + > + @param[in] SystemFirmwareImage Points to the System firmware imag= e. > + @param[in] SystemFirmwareImageSize The length of the System Firmware > image in bytes. > + @param[out] OtaCapsuleOffset The firmware image offset need to > updated. > + @param[out] OtaCapsuleSize The firmware image size need to > updated. > + > + @retval EFI_SUCCESS Get OTA Capsule firmware image inf= o > successfully. > + @retval others Some error occurs when executing t= his routine. > + > +**/ > +EFI_STATUS > +GetOtaCapsuleInfo ( > + IN VOID *SystemFirmwareImage, > + IN UINTN SystemFirmwareImageSize, > + OUT UINT32 *OtaCapsuleOffset, > + OUT UINT32 *OtaCapsuleSize > + ) > +{ > + EFI_STATUS Status; > + OTA_CAPSULE_UPDATE OtaCapsuleUpdateVal; > + // - UINTN VarSize; > + UINT32 UpdateOffset; > + UINT32 UpdateSize; > + > + if ((OtaCapsuleOffset =3D=3D NULL) || (OtaCapsuleSize =3D=3D NULL)) { > + return EFI_INVALID_PARAMETER; > + } > + > + DEBUG ((DEBUG_INFO, "GetOtaCapsuleInfo:")); > + DEBUG ((DEBUG_INFO, " Legnth - 0x%x\n", SystemFirmwareImageSize)); > + > + // - if (SystemFirmwareImageSize !=3D (UINTN) PcdGet32 (PcdFlashAreaS= ize)) > { > + // - return EFI_INVALID_PARAMETER; > + // - } > + if (SystemFirmwareImageSize !=3D (UINTN)(PcdGet32 (PcdFlashAreaSize)*2= )) > { > + return EFI_INVALID_PARAMETER; > + } > + > + ZeroMem (&OtaCapsuleUpdateVal, sizeof (OTA_CAPSULE_UPDATE)); > + > + /* > + VarSize =3D sizeof (OTA_CAPSULE_UPDATE); > + Status =3D gRT->GetVariable ( > + OTA_CAPSULE_VAR_NAME, > + &gOtaCapsuleUpdateGuid, > + NULL, > + &VarSize, > + (VOID *) &OtaCapsuleUpdateVal > + ); > + if (EFI_ERROR (Status)) { > + DEBUG ((DEBUG_ERROR, "GetOtaCapsuleInfo: GetVariable failed: %r\n"= , > Status)); > + return Status; > + } > + > + DEBUG ((DEBUG_INFO, "UpdateFlag: 0x%x, UpdateSlot: 0x%x\n", > OtaCapsuleUpdateVal.UpdateFlag, OtaCapsuleUpdateVal.UpdateSlot)); > + > + mUpdateSlot =3D OtaCapsuleUpdateVal.UpdateSlot; > + if (mUpdateSlot >=3D MAX_SLOT_NUM) { > + DEBUG ((DEBUG_ERROR, "Invalid Slot number: %d\n", mUpdateSlot)); > + return EFI_NOT_FOUND; > + } > + */ > + mUpdateSlot =3D 0; > + > + Status =3D VerifyImageLayout (SystemFirmwareImage, mUpdateSlot, > &UpdateOffset, &UpdateSize); > + if (EFI_ERROR (Status)) { > + DEBUG ((DEBUG_ERROR, "VerifyImageLayout failed: %r\n", Status)); > + return Status; > + } > + > + DEBUG ((DEBUG_INFO, "UpdateSlot: %d, UpdateOffset: 0x%x, UpdateSize: > 0x%x\n", mUpdateSlot, UpdateOffset, UpdateSize)); > + > + *OtaCapsuleOffset =3D UpdateOffset; > + *OtaCapsuleSize =3D UpdateSize; > + > + return EFI_SUCCESS; > +} > + > +/** > + Get OTA Capsule firmware image info. > + > + @param[in] SystemFirmwareImage Points to the System firmware imag= e. > + @param[in] SystemFirmwareImageSize The length of the System Firmware > image in bytes. > + @param[out] OtaCapsuleOffset The firmware image offset need to > updated. > + @param[out] OtaCapsuleSize The firmware image size need to > updated. > + > + @retval EFI_SUCCESS Get OTA Capsule firmware image inf= o > successfully. > + @retval others Some error occurs when executing t= his routine. > + > +**/ > +EFI_STATUS > +GetOtaCapsuleInfoSlotB ( > + IN VOID *SystemFirmwareImage, > + IN UINTN SystemFirmwareImageSize, > + OUT UINT32 *OtaCapsuleOffset, > + OUT UINT32 *OtaCapsuleSize > + ) > +{ > + EFI_STATUS Status; > + OTA_CAPSULE_UPDATE OtaCapsuleUpdateVal; > + // - UINTN VarSize; > + UINT32 UpdateOffset; > + UINT32 UpdateSize; > + > + // - if ((OtaCapsuleOffset =3D=3D NULL) || (OtaCapsuleSize =3D=3D NUL= L)) { > + // - return EFI_INVALID_PARAMETER; > + // - } > + > + DEBUG ((DEBUG_INFO, "GetOtaCapsuleInfo:")); > + DEBUG ((DEBUG_INFO, " Legnth - 0x%x\n", SystemFirmwareImageSize)); > + // - if (SystemFirmwareImageSize !=3D (UINTN) PcdGet32 (PcdFlashAreaS= ize)) > { > + // - return EFI_INVALID_PARAMETER; > + // - } > + // - if (SystemFirmwareImageSize !=3D (UINTN) (PcdGet32 > (PcdFlashAreaSize)*2)) { > + // - return EFI_INVALID_PARAMETER; > + // - } > + ZeroMem (&OtaCapsuleUpdateVal, sizeof (OTA_CAPSULE_UPDATE)); > + > + /* > + VarSize =3D sizeof (OTA_CAPSULE_UPDATE); > + Status =3D gRT->GetVariable ( > + OTA_CAPSULE_VAR_NAME, > + &gOtaCapsuleUpdateGuid, > + NULL, > + &VarSize, > + (VOID *) &OtaCapsuleUpdateVal > + ); > + if (EFI_ERROR (Status)) { > + DEBUG ((DEBUG_ERROR, "GetOtaCapsuleInfo: GetVariable failed: %r\n"= , > Status)); > + return Status; > + } > + > + DEBUG ((DEBUG_INFO, "UpdateFlag: 0x%x, UpdateSlot: 0x%x\n", > OtaCapsuleUpdateVal.UpdateFlag, OtaCapsuleUpdateVal.UpdateSlot)); > + > + mUpdateSlot =3D OtaCapsuleUpdateVal.UpdateSlot; > + if (mUpdateSlot >=3D MAX_SLOT_NUM) { > + DEBUG ((DEBUG_ERROR, "Invalid Slot number: %d\n", mUpdateSlot)); > + return EFI_NOT_FOUND; > + } > + */ > + mUpdateSlot =3D 1; > + > + Status =3D VerifyImageLayout (SystemFirmwareImage, mUpdateSlot, > &UpdateOffset, &UpdateSize); > + if (EFI_ERROR (Status)) { > + DEBUG ((DEBUG_ERROR, "VerifyImageLayout failed: %r\n", Status)); > + return Status; > + } > + > + DEBUG ((DEBUG_INFO, "UpdateSlot: %d, UpdateOffset: 0x%x, UpdateSize: > 0x%x\n", mUpdateSlot, UpdateOffset, UpdateSize)); > + > + *OtaCapsuleOffset =3D UpdateOffset; > + *OtaCapsuleSize =3D UpdateSize; > + > + return EFI_SUCCESS; > +} > + > +/** > + Update active slot information in ISH. > + > + @param[in] SlotNum The slot number will be set as act= ive. > + > + @retval EFI_SUCCESS Set active slto successfully. > + @retval others Some error occurs when executing t= his routine. > + > +**/ > +EFI_STATUS > +UpdateAbActiveSlot ( > + IN UINT8 SlotNum > + ) > +{ > + EFI_STATUS Status; > + IMAGE_SLOT_HEADER_INFO IshInfo; > + UINTN VarSize; > + > + DEBUG ((DEBUG_INFO, "UpdateAbActiveSlot...\n")); > + > + if (SlotNum >=3D MAX_SLOT_NUM) { > + return EFI_INVALID_PARAMETER; > + } > + > + ZeroMem (&IshInfo, sizeof (IMAGE_SLOT_HEADER_INFO)); > + > + VarSize =3D sizeof (IMAGE_SLOT_HEADER_INFO); > + Status =3D gRT->GetVariable ( > + ISH_VAR_NAME, > + &gABSupportUpdateIshGuid, > + NULL, > + &VarSize, > + (VOID *)&IshInfo > + ); > + if (EFI_ERROR (Status)) { > + DEBUG ((DEBUG_ERROR, "Get A/B slot info failed: %r\n", Status)); > + return Status; > + } > + > + DEBUG ((DEBUG_INFO, "Get IshInfo.SlotA_Priority: 0x%x\n", > IshInfo.SlotA_Priority)); > + DEBUG ((DEBUG_INFO, "Get IshInfo.SlotA_UpdateRetries: 0x%x\n", > IshInfo.SlotA_UpdateRetries)); > + DEBUG ((DEBUG_INFO, "Get IshInfo.SlotA_GlitchRetries: 0x%x\n", > IshInfo.SlotA_GlitchRetries)); > + DEBUG ((DEBUG_INFO, "Get IshInfo.SlotB_Priority: 0x%x\n", > IshInfo.SlotB_Priority)); > + DEBUG ((DEBUG_INFO, "Get IshInfo.SlotB_UpdateRetries: 0x%x\n", > IshInfo.SlotB_UpdateRetries)); > + DEBUG ((DEBUG_INFO, "Get IshInfo.SlotB_GlitchRetries: 0x%x\n\n", > IshInfo.SlotB_GlitchRetries)); > + > + if (SlotNum =3D=3D SLOT_A) { > + // Slot A > + if (IshInfo.SlotB_Priority =3D=3D MAX_UINT32) { > + IshInfo.SlotA_Priority =3D PcdGet32 (PcdFlashAbImageSlotDefaultPri= ority); > + IshInfo.SlotB_Priority =3D IshInfo.SlotA_Priority - 1; > + } else { > + IshInfo.SlotA_Priority =3D MAX (IshInfo.SlotA_Priority, > IshInfo.SlotB_Priority) + 1; > + } > + > + IshInfo.SlotA_UpdateRetries =3D 0xFF; > + } else if (SlotNum =3D=3D SLOT_B) { > + // Slot B > + if (IshInfo.SlotA_Priority =3D=3D MAX_UINT32) { > + IshInfo.SlotB_Priority =3D PcdGet32 (PcdFlashAbImageSlotDefaultPri= ority); > + IshInfo.SlotA_Priority =3D IshInfo.SlotB_Priority - 1; > + } else { > + IshInfo.SlotB_Priority =3D MAX (IshInfo.SlotA_Priority, > IshInfo.SlotB_Priority) + 1; > + } > + > + IshInfo.SlotB_UpdateRetries =3D 0xFF; > + } > + > + DEBUG ((DEBUG_INFO, "Set IshInfo.SlotA_Priority: 0x%x\n", > IshInfo.SlotA_Priority)); > + DEBUG ((DEBUG_INFO, "Set IshInfo.SlotA_UpdateRetries: 0x%x\n", > IshInfo.SlotA_UpdateRetries)); > + DEBUG ((DEBUG_INFO, "Set IshInfo.SlotA_GlitchRetries: 0x%x\n", > IshInfo.SlotA_GlitchRetries)); > + DEBUG ((DEBUG_INFO, "Set IshInfo.SlotB_Priority: 0x%x\n", > IshInfo.SlotB_Priority)); > + DEBUG ((DEBUG_INFO, "Set IshInfo.SlotB_UpdateRetries: 0x%x\n", > IshInfo.SlotB_UpdateRetries)); > + DEBUG ((DEBUG_INFO, "Set IshInfo.SlotB_GlitchRetries: 0x%x\n", > IshInfo.SlotB_GlitchRetries)); > + > + Status =3D gRT->SetVariable ( > + ISH_VAR_NAME, > + &gABSupportUpdateIshGuid, > + EFI_VARIABLE_BOOTSERVICE_ACCESS | > EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE, > + sizeof (IMAGE_SLOT_HEADER_INFO), > + (VOID *)&IshInfo > + ); > + if (EFI_ERROR (Status)) { > + DEBUG ((DEBUG_ERROR, "Set Slot info failed: %r\n", Status)); > + return Status; > + } > + > + return Status; > +} > + > +/** > + Update System Firmware image. > + > + @param[in] SystemFirmwareImage Points to the System Firmware > image. > + @param[in] SystemFirmwareImageSize The length of the System Firmware > image in bytes. > + @param[in] ConfigImage Points to the config file image. > + @param[in] ConfigImageSize The length of the config file imag= e in > bytes. > + @param[out] LastAttemptVersion The last attempt version, which wi= ll be > recorded in ESRT and FMP EFI_FIRMWARE_IMAGE_DESCRIPTOR. > + @param[out] LastAttemptStatus The last attempt status, which wil= l be > recorded in ESRT and FMP EFI_FIRMWARE_IMAGE_DESCRIPTOR. > + @param[in] Progress A function used by the driver to r= eport the > progress of the firmware update. > + > + @retval EFI_SUCCESS The System Firmware image is updated. > + @retval EFI_WRITE_PROTECTED The flash device is read only. > +**/ > +EFI_STATUS > +UpdateImage ( > + IN VOID *SystemFirmwareImage= , > + IN UINTN SystemFirmwareImageS= ize, > + IN VOID *ConfigImage, > + IN UINTN ConfigImageSize, > + OUT UINT32 *LastAttemptVersion, > + OUT UINT32 *LastAttemptStatus, > + IN EFI_FIRMWARE_MANAGEMENT_UPDATE_IMAGE_PROGRESS Progress > + ) > +{ > + EFI_STATUS Status; > + UPDATE_CONFIG_DATA *ConfigData; > + UPDATE_CONFIG_DATA *UpdateConfigData; > + CONFIG_HEADER ConfigHeader; > + UINTN Index; > + UINTN TotalSize; > + UINTN BytesWritten; > + UINTN StartPercentage; > + UINTN EndPercentage; > + UINT32 OtaCapsuleOffset; > + UINT32 OtaCapsuleSize; > + UINT32 ECImageSize; > + UINT32 ECImageOffset; > + > + if (ConfigImage =3D=3D NULL) { > + DEBUG ((DEBUG_INFO, "PlatformUpdate (NoConfig):")); > + // ASSUME the whole System Firmware include NVRAM region. > + StartPercentage =3D 0; > + EndPercentage =3D 100; > + if (Progress !=3D NULL) { > + Progress (StartPercentage); > + } > + > + ECImageSize =3D 0x20000; > + ECImageOffset =3D 0x0; > + > + DEBUG ((DEBUG_INFO, " BaseAddress - 0x%x,", ECImageOffset)); > + DEBUG ((DEBUG_INFO, " Length - 0x%x\n", ECImageSize)); > + > + Status =3D PerformFlashWriteWithProgress ( > + PlatformFirmwareTypeNvRam, > + (EFI_PHYSICAL_ADDRESS)ECImageOffset, > + FlashAddressTypeRelativeAddress, > + (VOID *)((UINT8 *)SystemFirmwareImage + ECImageOffset), > + ECImageSize, > + Progress, > + StartPercentage, > + EndPercentage > + ); > + if (Progress !=3D NULL) { > + Progress (EndPercentage); > + } > + > + if (!EFI_ERROR (Status)) { > + *LastAttemptStatus =3D LAST_ATTEMPT_STATUS_SUCCESS; > + mNvRamUpdated =3D TRUE; > + } else { > + *LastAttemptStatus =3D LAST_ATTEMPT_STATUS_ERROR_UNSUCCESSFUL; > + } > + > + StartPercentage =3D 0; > + EndPercentage =3D 100; > + if (Progress !=3D NULL) { > + Progress (StartPercentage); > + } > + > + Status =3D GetOtaCapsuleInfo (SystemFirmwareImage, > SystemFirmwareImageSize, &OtaCapsuleOffset, &OtaCapsuleSize); > + if (EFI_ERROR (Status)) { > + DEBUG ((DEBUG_ERROR, "GetOtaCapsuleInfo failed: %r\n", Status)); > + *LastAttemptStatus =3D LAST_ATTEMPT_STATUS_ERROR_UNSUCCESSFUL; > + return Status; > + } > + > + DEBUG ((DEBUG_INFO, " BaseAddress - 0x%x,", OtaCapsuleOffset)); > + DEBUG ((DEBUG_INFO, " Length - 0x%x\n", OtaCapsuleSize)); > + > + Status =3D PerformFlashWriteWithProgress ( > + PlatformFirmwareTypeNvRam, > + (EFI_PHYSICAL_ADDRESS)OtaCapsuleOffset, > + FlashAddressTypeRelativeAddress, > + (VOID *)((UINT8 *)SystemFirmwareImage + OtaCapsuleOffset)= , > + OtaCapsuleSize, > + Progress, > + StartPercentage, > + EndPercentage > + ); > + if (Progress !=3D NULL) { > + Progress (EndPercentage); > + } > + > + if (!EFI_ERROR (Status)) { > + *LastAttemptStatus =3D LAST_ATTEMPT_STATUS_SUCCESS; > + mNvRamUpdated =3D TRUE; > + } else { > + *LastAttemptStatus =3D LAST_ATTEMPT_STATUS_ERROR_UNSUCCESSFUL; > + } > + > + Status =3D GetOtaCapsuleInfoSlotB (SystemFirmwareImage, > SystemFirmwareImageSize, &OtaCapsuleOffset, &OtaCapsuleSize); > + if (EFI_ERROR (Status)) { > + DEBUG ((DEBUG_ERROR, "GetOtaCapsuleInfo failed: %r\n", Status)); > + *LastAttemptStatus =3D LAST_ATTEMPT_STATUS_ERROR_UNSUCCESSFUL; > + return Status; > + } > + > + DEBUG ((DEBUG_INFO, " BaseAddress - 0x%x,", OtaCapsuleOffset)); > + DEBUG ((DEBUG_INFO, " Length - 0x%x\n", OtaCapsuleSize)); > + > + Status =3D PerformFlashWriteWithProgress ( > + PlatformFirmwareTypeNvRam, > + (EFI_PHYSICAL_ADDRESS)OtaCapsuleOffset, > + FlashAddressTypeRelativeAddress, > + (VOID *)((UINT8 *)SystemFirmwareImage + OtaCapsuleOffset)= , > + OtaCapsuleSize, > + Progress, > + StartPercentage, > + EndPercentage > + ); > + if (Progress !=3D NULL) { > + Progress (EndPercentage); > + } > + > + if (!EFI_ERROR (Status)) { > + *LastAttemptStatus =3D LAST_ATTEMPT_STATUS_SUCCESS; > + mNvRamUpdated =3D TRUE; > + } else { > + *LastAttemptStatus =3D LAST_ATTEMPT_STATUS_ERROR_UNSUCCESSFUL; > + } > + > + return Status; > + } > + > + DEBUG ((DEBUG_INFO, "PlatformUpdate (With Config):\n")); > + ConfigData =3D NULL; > + ZeroMem (&ConfigHeader, sizeof (ConfigHeader)); > + Status =3D ParseUpdateDataFile ( > + ConfigImage, > + ConfigImageSize, > + &ConfigHeader, > + &ConfigData > + ); > + DEBUG ((DEBUG_INFO, "ParseUpdateDataFile - %r\n", Status)); > + if (EFI_ERROR (Status)) { > + *LastAttemptStatus =3D LAST_ATTEMPT_STATUS_ERROR_UNSUCCESSFUL; > + return EFI_INVALID_PARAMETER; > + } > + > + DEBUG ((DEBUG_INFO, "ConfigHeader.NumOfUpdates - 0x%x\n", > ConfigHeader.NumOfUpdates)); > + DEBUG ((DEBUG_INFO, "PcdEdkiiSystemFirmwareFileGuid - %g\n", > PcdGetPtr (PcdEdkiiSystemFirmwareFileGuid))); > + > + TotalSize =3D 0; > + for (Index =3D 0; Index < ConfigHeader.NumOfUpdates; Index++) { > + if (CompareGuid (&ConfigData[Index].FileGuid, PcdGetPtr > (PcdEdkiiSystemFirmwareFileGuid))) { > + TotalSize =3D TotalSize + ConfigData[Index].Length; > + } > + } > + > + BytesWritten =3D 0; > + Index =3D 0; > + UpdateConfigData =3D ConfigData; > + while (Index < ConfigHeader.NumOfUpdates) { > + if (CompareGuid (&UpdateConfigData->FileGuid, PcdGetPtr > (PcdEdkiiSystemFirmwareFileGuid))) { > + DEBUG ((DEBUG_INFO, "FileGuid - %g (processing)\n", > &UpdateConfigData->FileGuid)); > + StartPercentage =3D (BytesWritten * 100) / TotalSize; > + EndPercentage =3D ((BytesWritten + UpdateConfigData->Length) * 1= 00) / > TotalSize; > + Status =3D PerformUpdate ( > + SystemFirmwareImage, > + SystemFirmwareImageSize, > + UpdateConfigData, > + LastAttemptVersion, > + LastAttemptStatus, > + Progress, > + StartPercentage, > + EndPercentage > + ); > + // > + // Shall updates be serialized so that if an update is not success= fully > completed, > + // the remaining updates won't be performed. > + // > + if (EFI_ERROR (Status)) { > + break; > + } > + } else { > + DEBUG ((DEBUG_INFO, "FileGuid - %g (ignored)\n", &UpdateConfigData= - > >FileGuid)); > + } > + > + BytesWritten +=3D UpdateConfigData->Length; > + > + Index++; > + UpdateConfigData++; > + } > + > + return Status; > +} > + > +/** > + Authenticate and update System Firmware image. > + > + Caution: This function may receive untrusted input. > + > + @param[in] Image The EDKII system FMP capsule image. > + @param[in] ImageSize The size of the EDKII system FMP capsul= e image > in bytes. > + @param[out] LastAttemptVersion The last attempt version, which will be > recorded in ESRT and FMP EFI_FIRMWARE_IMAGE_DESCRIPTOR. > + @param[out] LastAttemptStatus The last attempt status, which will be > recorded in ESRT and FMP EFI_FIRMWARE_IMAGE_DESCRIPTOR. > + @param[in] Progress A function used by the driver to report= the > progress of the firmware update. > + > + @retval EFI_SUCCESS EDKII system FMP capsule passes > authentication and the System Firmware image is updated. > + @retval EFI_SECURITY_VIOLATION EDKII system FMP capsule fails > authentication and the System Firmware image is not updated. > + @retval EFI_WRITE_PROTECTED The flash device is read only. > +**/ > +EFI_STATUS > +SystemFirmwareAuthenticatedUpdate ( > + IN VOID *Image, > + IN UINTN ImageSize, > + OUT UINT32 *LastAttemptVersion, > + OUT UINT32 *LastAttemptStatus, > + IN EFI_FIRMWARE_MANAGEMENT_UPDATE_IMAGE_PROGRESS Progress > + ) > +{ > + EFI_STATUS Status; > + VOID *SystemFirmwareImage; > + UINTN SystemFirmwareImageSize; > + VOID *ConfigImage; > + UINTN ConfigImageSize; > + VOID *AuthenticatedImage; > + UINTN AuthenticatedImageSize; > + > + AuthenticatedImage =3D NULL; > + AuthenticatedImageSize =3D 0; > + > + DEBUG ((DEBUG_INFO, "SystemFirmwareAuthenticatedUpdate...\n")); > + > + Status =3D CapsuleAuthenticateSystemFirmware (Image, ImageSize, FALSE, > LastAttemptVersion, LastAttemptStatus, &AuthenticatedImage, > &AuthenticatedImageSize); > + if (EFI_ERROR (Status)) { > + DEBUG ((DEBUG_INFO, "SystemFirmwareAuthenticateImage - %r\n", > Status)); > + return Status; > + } > + > + DEBUG ((DEBUG_INFO, "ExtractSystemFirmwareImage ...\n")); > + ExtractSystemFirmwareImage (AuthenticatedImage, > AuthenticatedImageSize, &SystemFirmwareImage, > &SystemFirmwareImageSize); > + DEBUG ((DEBUG_INFO, "ExtractConfigImage ...\n")); > + ExtractConfigImage (AuthenticatedImage, AuthenticatedImageSize, > &ConfigImage, &ConfigImageSize); > + > + DEBUG ((DEBUG_INFO, "UpdateImage ...\n")); > + Status =3D UpdateImage (SystemFirmwareImage, SystemFirmwareImageSize, > ConfigImage, ConfigImageSize, LastAttemptVersion, LastAttemptStatus, > Progress); > + if (EFI_ERROR (Status)) { > + DEBUG ((DEBUG_INFO, "UpdateImage - %r\n", Status)); > + return Status; > + } > + > + #if 0 > + // DO NOT KNOW THE REASON to update A/B Active Slot. > + // Removed FOR NOW. > + > + // > + // Update A/B active slot info > + // > + Status =3D UpdateAbActiveSlot (mUpdateSlot); > + if (EFI_ERROR (Status)) { > + DEBUG ((DEBUG_ERROR, "UpdateAbActiveSlot failed: %r\n", Status)); > + return Status; > + } > + > + DEBUG ((DEBUG_INFO, "SystemFirmwareAuthenticatedUpdate Done\n")); > + #endif > + return Status; > +} > + > +/** > + > + This code finds variable in storage blocks (Volatile or Non-Volatile). > + > + @param[in] VariableName Name of Variable to be foun= d. > + @param[in] VendorGuid Variable vendor GUID. > + @param[out] Attributes Attribute value of the vari= able found. > + @param[in, out] DataSize Size of Data found. If size= is less than the > + data, this value contains t= he required size. > + @param[out] Data Data pointer. > + > + @return EFI_INVALID_PARAMETER Invalid parameter. > + @return EFI_SUCCESS Find the specified variable. > + @return EFI_NOT_FOUND Not found. > + @return EFI_BUFFER_TO_SMALL DataSize is too small for the result= . > + > +**/ > +EFI_STATUS > +EFIAPI > +GetVariableHook ( > + IN CHAR16 *VariableName, > + IN EFI_GUID *VendorGuid, > + OUT UINT32 *Attributes OPTIONAL, > + IN OUT UINTN *DataSize, > + OUT VOID *Data > + ) > +{ > + DEBUG ((DEBUG_INFO, "GetVariableHook - %S, %g\n", VariableName, > VendorGuid)); > + return EFI_NOT_AVAILABLE_YET; > +} > + > +/** > + > + This code Finds the Next available variable. > + > + @param[in, out] VariableNameSize Size of the variable name. > + @param[in, out] VariableName Pointer to variable name. > + @param[in, out] VendorGuid Variable Vendor Guid. > + > + @return EFI_INVALID_PARAMETER Invalid parameter. > + @return EFI_SUCCESS Find the specified variable. > + @return EFI_NOT_FOUND Not found. > + @return EFI_BUFFER_TO_SMALL DataSize is too small for the result= . > + > +**/ > +EFI_STATUS > +EFIAPI > +GetNextVariableNameHook ( > + IN OUT UINTN *VariableNameSize, > + IN OUT CHAR16 *VariableName, > + IN OUT EFI_GUID *VendorGuid > + ) > +{ > + DEBUG ((DEBUG_INFO, "GetNextVariableNameHook - %S, %g\n", > VariableName, VendorGuid)); > + return EFI_NOT_AVAILABLE_YET; > +} > + > +/** > + > + This code sets variable in storage blocks (Volatile or Non-Volatile). > + > + @param[in] VariableName Name of Variable to be fou= nd. > + @param[in] VendorGuid Variable vendor GUID. > + @param[in] Attributes Attribute value of the var= iable found > + @param[in] DataSize Size of Data found. If siz= e is less than the > + data, this value contains = the required size. > + @param[in] Data Data pointer. > + > + @return EFI_INVALID_PARAMETER Invalid parameter. > + @return EFI_SUCCESS Set successfully. > + @return EFI_OUT_OF_RESOURCES Resource not enough to set > variable. > + @return EFI_NOT_FOUND Not found. > + @return EFI_WRITE_PROTECTED Variable is read-only. > + > +**/ > +EFI_STATUS > +EFIAPI > +SetVariableHook ( > + IN CHAR16 *VariableName, > + IN EFI_GUID *VendorGuid, > + IN UINT32 Attributes, > + IN UINTN DataSize, > + IN VOID *Data > + ) > +{ > + DEBUG ((DEBUG_INFO, "SetVariableHook - %S, %g, 0x%x (0x%x)\n", > VariableName, VendorGuid, Attributes, DataSize)); > + return EFI_NOT_AVAILABLE_YET; > +} > + > +/** > + > + This code returns information about the EFI variables. > + > + @param[in] Attributes Attributes bitmask to speci= fy the type of > variables > + on which to return informat= ion. > + @param[out] MaximumVariableStorageSize Pointer to the maximum size > of the storage space available > + for the EFI variables assoc= iated with the attributes > specified. > + @param[out] RemainingVariableStorageSize Pointer to the remaining si= ze > of the storage space available > + for EFI variables associate= d with the attributes > specified. > + @param[out] MaximumVariableSize Pointer to the maximum size= of > an individual EFI variables > + associated with the attribu= tes specified. > + > + @return EFI_SUCCESS Query successfully. > + > +**/ > +EFI_STATUS > +EFIAPI > +QueryVariableInfoHook ( > + IN UINT32 Attributes, > + OUT UINT64 *MaximumVariableStorageSize, > + OUT UINT64 *RemainingVariableStorageSize, > + OUT UINT64 *MaximumVariableSize > + ) > +{ > + DEBUG ((DEBUG_INFO, "QueryVariableInfoHook - 0x%x\n", Attributes)); > + return EFI_NOT_AVAILABLE_YET; > +} > + > +/** > + Updates the firmware image of the device. > + > + This function updates the hardware with the new firmware image. > + This function returns EFI_UNSUPPORTED if the firmware image is not > updatable. > + If the firmware image is updatable, the function should perform the > following minimal validations > + before proceeding to do the firmware image update. > + - Validate the image authentication if image has attribute > + IMAGE_ATTRIBUTE_AUTHENTICATION_REQUIRED. The function returns > + EFI_SECURITY_VIOLATION if the validation fails. > + - Validate the image is a supported image for this device. The functio= n > returns EFI_ABORTED if > + the image is unsupported. The function can optionally provide more > detailed information on > + why the image is not a supported image. > + - Validate the data from VendorCode if not null. Image validation must= be > performed before > + VendorCode data validation. VendorCode data is ignored or considered > invalid if image > + validation failed. The function returns EFI_ABORTED if the data is i= nvalid. > + > + VendorCode enables vendor to implement vendor-specific firmware image > update policy. Null if > + the caller did not specify the policy or use the default policy. As an= example, > vendor can implement > + a policy to allow an option to force a firmware image update when the = abort > reason is due to the new > + firmware image version is older than the current firmware image versio= n or > bad image checksum. > + Sensitive operations such as those wiping the entire firmware image an= d > render the device to be > + non-functional should be encoded in the image itself rather than passe= d > with the VendorCode. > + AbortReason enables vendor to have the option to provide a more detail= ed > description of the abort > + reason to the caller. > + > + @param[in] This A pointer to the > EFI_FIRMWARE_MANAGEMENT_PROTOCOL instance. > + @param[in] ImageIndex A unique number identifying the firmwar= e > image(s) within the device. > + The number is between 1 and DescriptorC= ount. > + @param[in] Image Points to the new image. > + @param[in] ImageSize Size of the new image in bytes. > + @param[in] VendorCode This enables vendor to implement vendor= - > specific firmware image update policy. > + Null indicates the caller did not speci= fy the policy or use the > default policy. > + @param[in] Progress A function used by the driver to report= the > progress of the firmware update. > + @param[out] AbortReason A pointer to a pointer to a null-termin= ated > string providing more > + details for the aborted operation. The = buffer is allocated by > this function > + with AllocatePool(), and it is the call= er's responsibility to free > it with a > + call to FreePool(). > + > + @retval EFI_SUCCESS The device was successfully updated wit= h the > new image. > + @retval EFI_ABORTED The operation is aborted. > + @retval EFI_INVALID_PARAMETER The Image was NULL. > + @retval EFI_UNSUPPORTED The operation is not supported. > + @retval EFI_SECURITY_VIOLATION The operation could not be performed > due to an authentication failure. > + > +**/ > +EFI_STATUS > +EFIAPI > +FmpSetImage ( > + IN EFI_FIRMWARE_MANAGEMENT_PROTOCOL *This, > + IN UINT8 ImageIndex, > + IN CONST VOID *Image, > + IN UINTN ImageSize, > + IN CONST VOID *VendorCode, > + IN EFI_FIRMWARE_MANAGEMENT_UPDATE_IMAGE_PROGRESS Progress, > + OUT CHAR16 **AbortReason > + ) > +{ > + EFI_STATUS Status; > + EFI_STATUS VarStatus; > + SYSTEM_FMP_PRIVATE_DATA *SystemFmpPrivate; > + > + if ((Image =3D=3D NULL) || (ImageSize =3D=3D 0) || (AbortReason =3D=3D= NULL)) { > + return EFI_INVALID_PARAMETER; > + } > + > + SystemFmpPrivate =3D SYSTEM_FMP_PRIVATE_DATA_FROM_FMP (This); > + *AbortReason =3D NULL; > + > + if ((ImageIndex =3D=3D 0) || (ImageIndex > SystemFmpPrivate- > >DescriptorCount)) { > + return EFI_INVALID_PARAMETER; > + } > + > + Status =3D SystemFirmwareAuthenticatedUpdate ((VOID *)Image, ImageSize= , > &SystemFmpPrivate->LastAttempt.LastAttemptVersion, &SystemFmpPrivate- > >LastAttempt.LastAttemptStatus, Progress); > + DEBUG ((DEBUG_INFO, "SetImage - LastAttempt Version - 0x%x, State - > 0x%x\n", SystemFmpPrivate->LastAttempt.LastAttemptVersion, > SystemFmpPrivate->LastAttempt.LastAttemptStatus)); > + > + // > + // If NVRAM is updated, we should no longer touch variable services, > because > + // the current variable driver may not manage the new NVRAM region. > + // > + if (mNvRamUpdated) { > + DEBUG ((DEBUG_INFO, "NvRamUpdated, Update Variable Serivces\n")); > + gRT->GetVariable =3D GetVariableHook; > + gRT->GetNextVariableName =3D GetNextVariableNameHook; > + gRT->SetVariable =3D SetVariableHook; > + gRT->QueryVariableInfo =3D QueryVariableInfoHook; > + > + gRT->Hdr.CRC32 =3D 0; > + gBS->CalculateCrc32 ( > + (UINT8 *)&gRT->Hdr, > + gRT->Hdr.HeaderSize, > + &gRT->Hdr.CRC32 > + ); > + } > + > + VarStatus =3D gRT->SetVariable ( > + SYSTEM_FMP_LAST_ATTEMPT_VARIABLE_NAME, > + &gSystemFmpLastAttemptVariableGuid, > + EFI_VARIABLE_NON_VOLATILE | > EFI_VARIABLE_BOOTSERVICE_ACCESS, > + sizeof (SystemFmpPrivate->LastAttempt), > + &SystemFmpPrivate->LastAttempt > + ); > + DEBUG ((DEBUG_INFO, "SetLastAttemp - %r\n", VarStatus)); > + > + return Status; > +} > + > +/** > + Get the set of EFI_FIRMWARE_IMAGE_DESCRIPTOR structures from an FMP > Protocol. > + > + @param[in] Handle Handle with an FMP Protocol or a System= FMP > + Protocol. > + @param[in] ProtocolGuid Pointer to the FMP Protocol GUID or Sys= tem > FMP > + Protocol GUID. > + @param[out] FmpImageInfoCount Pointer to the number of > + EFI_FIRMWARE_IMAGE_DESCRIPTOR structure= s. > + @param[out] DescriptorSize Pointer to the size, in bytes, of each > + EFI_FIRMWARE_IMAGE_DESCRIPTOR structure= . > + > + @return NULL No EFI_FIRMWARE_IMAGE_DESCRIPTOR structures found. > + @return !NULL Pointer to a buffer of EFI_FIRMWARE_IMAGE_DESCRIPTOR > structures > + allocated using AllocatePool(). Caller must free buffe= r with > + FreePool(). > +**/ > +EFI_FIRMWARE_IMAGE_DESCRIPTOR * > +GetFmpImageDescriptors ( > + IN EFI_HANDLE Handle, > + IN EFI_GUID *ProtocolGuid, > + OUT UINT8 *FmpImageInfoCount, > + OUT UINTN *DescriptorSize > + ) > +{ > + EFI_STATUS Status; > + EFI_FIRMWARE_MANAGEMENT_PROTOCOL *Fmp; > + UINTN ImageInfoSize; > + EFI_FIRMWARE_IMAGE_DESCRIPTOR *FmpImageInfoBuf; > + UINT32 FmpImageInfoDescriptorVer; > + UINT32 PackageVersion; > + CHAR16 *PackageVersionName; > + > + *FmpImageInfoCount =3D 0; > + *DescriptorSize =3D 0; > + > + Status =3D gBS->HandleProtocol ( > + Handle, > + ProtocolGuid, > + (VOID **)&Fmp > + ); > + if (EFI_ERROR (Status)) { > + return NULL; > + } > + > + // > + // Determine the size required for the set of > EFI_FIRMWARE_IMAGE_DESCRIPTORs. > + // > + ImageInfoSize =3D 0; > + Status =3D Fmp->GetImageInfo ( > + Fmp, // FMP Pointer > + &ImageInfoSize, // Buffer Size (in = this case 0) > + NULL, // NULL so we can g= et size > + &FmpImageInfoDescriptorVer, // DescriptorVersio= n > + FmpImageInfoCount, // DescriptorCount > + DescriptorSize, // DescriptorSize > + &PackageVersion, // PackageVersion > + &PackageVersionName // PackageVersionNa= me > + ); > + if (Status !=3D EFI_BUFFER_TOO_SMALL) { > + DEBUG ((DEBUG_ERROR, "SystemFirmwareUpdateDxe: Unexpected > Failure. Status =3D %r\n", Status)); > + return NULL; > + } > + > + // > + // Allocate buffer for the set of EFI_FIRMWARE_IMAGE_DESCRIPTORs. > + // > + FmpImageInfoBuf =3D NULL; > + FmpImageInfoBuf =3D AllocateZeroPool (ImageInfoSize); > + if (FmpImageInfoBuf =3D=3D NULL) { > + DEBUG ((DEBUG_ERROR, "SystemFirmwareUpdateDxe: Failed to allocate > memory for descriptors.\n")); > + return NULL; > + } > + > + // > + // Retrieve the set of EFI_FIRMWARE_IMAGE_DESCRIPTORs. > + // > + PackageVersionName =3D NULL; > + Status =3D Fmp->GetImageInfo ( > + Fmp, > + &ImageInfoSize, // ImageInfoSi= ze > + FmpImageInfoBuf, // ImageInfo > + &FmpImageInfoDescriptorVer, // DescriptorV= ersion > + FmpImageInfoCount, // DescriptorC= ount > + DescriptorSize, // DescriptorS= ize > + &PackageVersion, // PackageVers= ion > + &PackageVersionName // PackageVers= ionName > + ); > + > + // > + // Free unused PackageVersionName return buffer > + // > + if (PackageVersionName !=3D NULL) { > + FreePool (PackageVersionName); > + PackageVersionName =3D NULL; > + } > + > + if (EFI_ERROR (Status)) { > + DEBUG ((DEBUG_ERROR, "SystemFirmwareUpdateDxe: Failure in > GetImageInfo. Status =3D %r\n", Status)); > + if (FmpImageInfoBuf !=3D NULL) { > + FreePool (FmpImageInfoBuf); > + } > + > + return NULL; > + } > + > + return FmpImageInfoBuf; > +} > + > +/** > + Search for handles with an FMP protocol whose > EFI_FIRMWARE_IMAGE_DESCRIPTOR > + ImageTypeId matches the ImageTypeId produced by this module. > + > + @param[in] ProtocolGuid Pointer to the GUID of the protocol to searc= h. > + @param[out] HandleCount Pointer to the number of returned handles. > + > + @return NULL No matching handles found. > + @return !NULL Pointer to a buffer of handles allocated using Allocate= Pool(). > + Caller must free buffer with FreePool(). > +**/ > +EFI_HANDLE * > +FindMatchingFmpHandles ( > + IN EFI_GUID *ProtocolGuid, > + OUT UINTN *HandleCount > + ) > +{ > + EFI_STATUS Status; > + UINTN TempHandleCount; > + EFI_HANDLE *HandleBuffer; > + UINTN Index; > + UINTN Index2; > + UINTN Index3; > + EFI_FIRMWARE_IMAGE_DESCRIPTOR *OriginalFmpImageInfoBuf; > + EFI_FIRMWARE_IMAGE_DESCRIPTOR *FmpImageInfoBuf; > + UINT8 FmpImageInfoCount; > + UINTN DescriptorSize; > + BOOLEAN MatchFound; > + > + *HandleCount =3D 0; > + TempHandleCount =3D 0; > + HandleBuffer =3D NULL; > + Status =3D gBS->LocateHandleBuffer ( > + ByProtocol, > + ProtocolGuid, > + NULL, > + &TempHandleCount, > + &HandleBuffer > + ); > + if (EFI_ERROR (Status)) { > + return NULL; > + } > + > + for (Index =3D 0; Index < TempHandleCount; Index++) { > + OriginalFmpImageInfoBuf =3D GetFmpImageDescriptors ( > + HandleBuffer[Index], > + ProtocolGuid, > + &FmpImageInfoCount, > + &DescriptorSize > + ); > + > + // > + // Loop through the set of EFI_FIRMWARE_IMAGE_DESCRIPTORs. > + // > + MatchFound =3D FALSE; > + if (OriginalFmpImageInfoBuf !=3D NULL) { > + FmpImageInfoBuf =3D OriginalFmpImageInfoBuf; > + > + for (Index2 =3D 0; Index2 < FmpImageInfoCount; Index2++) { > + for (Index3 =3D 0; Index3 < mSystemFmpPrivate->DescriptorCount; > Index3++) { > + MatchFound =3D CompareGuid ( > + &FmpImageInfoBuf->ImageTypeId, > + &mSystemFmpPrivate->ImageDescriptor[Index3].Ima= geTypeId > + ); > + if (MatchFound) { > + break; > + } > + } > + > + if (MatchFound) { > + break; > + } > + > + // > + // Increment the buffer pointer ahead by the size of the descrip= tor > + // > + FmpImageInfoBuf =3D (EFI_FIRMWARE_IMAGE_DESCRIPTOR *)(((UINT8 > *)FmpImageInfoBuf) + DescriptorSize); > + } > + > + if (MatchFound) { > + HandleBuffer[*HandleCount] =3D HandleBuffer[Index]; > + (*HandleCount)++; > + } > + > + FreePool (OriginalFmpImageInfoBuf); > + } > + } > + > + if ((*HandleCount) =3D=3D 0) { > + // > + // No any matching handle. > + // > + FreePool (HandleBuffer); > + return NULL; > + } > + > + return HandleBuffer; > +} > + > +/** > + Uninstall System FMP Protocol instances that may have been installed b= y > + SystemFirmwareUpdateDxe drivers dispatches by other capsules. > + > + @retval EFI_SUCCESS All System FMP Protocols found were uninstalled. > + @return Other One or more System FMP Protocols could not be > uninstalled. > + > +**/ > +EFI_STATUS > +UninstallMatchingSystemFmpProtocols ( > + VOID > + ) > +{ > + EFI_STATUS Status; > + EFI_HANDLE *HandleBuffer; > + UINTN HandleCount; > + UINTN Index; > + EFI_FIRMWARE_MANAGEMENT_PROTOCOL *SystemFmp; > + > + // > + // Uninstall SystemFmpProtocol instances that may have been produced b= y > + // the SystemFirmwareUpdate drivers in FVs dispatched by other capsule= s. > + // > + HandleBuffer =3D FindMatchingFmpHandles ( > + &gSystemFmpProtocolGuid, > + &HandleCount > + ); > + DEBUG ((DEBUG_INFO, "SystemFirmwareUpdateDxe: Found %d matching > System FMP instances\n", HandleCount)); > + > + for (Index =3D 0; Index < HandleCount; Index++) { > + Status =3D gBS->HandleProtocol ( > + HandleBuffer[Index], > + &gSystemFmpProtocolGuid, > + (VOID **)&SystemFmp > + ); > + if (EFI_ERROR (Status)) { > + continue; > + } > + > + DEBUG ((DEBUG_INFO, "SystemFirmwareUpdateDxe: Uninstall > SystemFmp produced by another capsule\n")); > + Status =3D gBS->UninstallProtocolInterface ( > + HandleBuffer[Index], > + &gSystemFmpProtocolGuid, > + SystemFmp > + ); > + if (EFI_ERROR (Status)) { > + DEBUG ((DEBUG_ERROR, "SystemFirmwareUpdateDxe: Failed to uninstall > SystemFmp %r. Exiting.\n", Status)); > + FreePool (HandleBuffer); > + return Status; > + } > + } > + > + if (HandleBuffer !=3D NULL) { > + FreePool (HandleBuffer); > + } > + > + return EFI_SUCCESS; > +} > + > +/** > + System FMP module entrypoint > + > + @param[in] ImageHandle The firmware allocated handle for the EFI imag= e. > + @param[in] SystemTable A pointer to the EFI System Table. > + > + @retval EFI_SUCCESS System FMP module is initialized. > + @retval EFI_OUT_OF_RESOURCES There are not enough resources > avaulable to > + initialize this module. > + @retval Other System FMP Protocols could not be uninst= alled. > + @retval Other System FMP Protocol could not be install= ed. > + @retval Other FMP Protocol could not be installed. > +**/ > +EFI_STATUS > +EFIAPI > +SystemFirmwareUpdateMainDxe ( > + IN EFI_HANDLE ImageHandle, > + IN EFI_SYSTEM_TABLE *SystemTable > + ) > +{ > + EFI_STATUS Status; > + EFI_HANDLE *HandleBuffer; > + UINTN HandleCount; > + > + // > + // Initialize SystemFmpPrivateData > + // > + mSystemFmpPrivate =3D AllocateZeroPool (sizeof > (SYSTEM_FMP_PRIVATE_DATA)); > + if (mSystemFmpPrivate =3D=3D NULL) { > + return EFI_OUT_OF_RESOURCES; > + } > + > + Status =3D InitializePrivateData (mSystemFmpPrivate); > + if (EFI_ERROR (Status)) { > + FreePool (mSystemFmpPrivate); > + mSystemFmpPrivate =3D NULL; > + return Status; > + } > + > + // > + // Uninstall SystemFmpProtocol instances that may have been produced b= y > + // the SystemFirmwareUpdate drivers in FVs dispatched by other capsule= s. > + // > + Status =3D UninstallMatchingSystemFmpProtocols (); > + if (EFI_ERROR (Status)) { > + FreePool (mSystemFmpPrivate); > + mSystemFmpPrivate =3D NULL; > + return Status; > + } > + > + // > + // Look for a handle with matching Firmware Management Protocol > + // > + HandleCount =3D 0; > + HandleBuffer =3D FindMatchingFmpHandles ( > + &gEfiFirmwareManagementProtocolGuid, > + &HandleCount > + ); > + DEBUG ((DEBUG_INFO, "SystemFirmwareUpdateDxe: Found %d matching > FMP instances\n", HandleCount)); > + > + switch (HandleCount) { > + case 0: > + // > + // Install FMP protocol onto a new handle. > + // > + DEBUG ((DEBUG_INFO, "SystemFirmwareUpdateDxe: Install FMP onto a > new handle\n")); > + Status =3D gBS->InstallMultipleProtocolInterfaces ( > + &mSystemFmpPrivate->Handle, > + &gEfiFirmwareManagementProtocolGuid, > + &mSystemFmpPrivate->Fmp, > + NULL > + ); > + break; > + case 1: > + // > + // Install System FMP protocol onto handle with matching FMP Proto= col > + // > + DEBUG ((DEBUG_INFO, "SystemFirmwareUpdateDxe: Install System FMP > onto matching FMP handle\n")); > + mSystemFmpPrivate->Handle =3D HandleBuffer[0]; > + Status =3D gBS->InstallMultipleProtocolInterfac= es ( > + &HandleBuffer[0], > + &gSystemFmpProtocolGuid, > + &mSystemFmpPrivate->Fmp, > + NULL > + ); > + break; > + default: > + // > + // More than one matching handle is not expected. Unload driver. > + // > + DEBUG ((DEBUG_ERROR, "SystemFirmwareUpdateDxe: More than one > matching FMP handle. Unload driver.\n")); > + Status =3D EFI_DEVICE_ERROR; > + break; > + } > + > + if (HandleBuffer !=3D NULL) { > + FreePool (HandleBuffer); > + } > + > + if (EFI_ERROR (Status)) { > + FreePool (mSystemFmpPrivate); > + mSystemFmpPrivate =3D NULL; > + } > + > + return Status; > +} > diff --git > a/Platform/AMD/VanGoghBoard/Override/edk2/SignedCapsulePkg/Universal > /SystemFirmwareUpdate/SystemFirmwareUpdateDxe.inf > b/Platform/AMD/VanGoghBoard/Override/edk2/SignedCapsulePkg/Universa > l/SystemFirmwareUpdate/SystemFirmwareUpdateDxe.inf > new file mode 100644 > index 0000000000..aff752007d > --- /dev/null > +++ > b/Platform/AMD/VanGoghBoard/Override/edk2/SignedCapsulePkg/Universa > l/SystemFirmwareUpdate/SystemFirmwareUpdateDxe.inf > @@ -0,0 +1,91 @@ > +## @file > +# System Firmware Update Dxe > +# > +# Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved. > +# SPDX-License-Identifier: BSD-2-Clause-Patent > +# > +## > + > +## @file > +# SystemFirmware FMP update driver. > +# > +# Produce FMP instance to update system firmware. > +# > +# Copyright (c) 2016, Intel Corporation. All rights reserved.
> +# This program and the accompanying materials > +# are licensed and made available under the terms and conditions of the= BSD > License > +# which accompanies this distribution. The full text of the license ma= y be > found at > +# http://opensource.org/licenses/bsd-license.php > +# > +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" > BASIS, > +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER > EXPRESS OR IMPLIED. > +# > +## > + > +[Defines] > + INF_VERSION =3D 0x00010005 > + BASE_NAME =3D SystemFirmwareUpdateDxe > + MODULE_UNI_FILE =3D SystemFirmwareUpdateDxe.uni > + FILE_GUID =3D 0A2FBD15-1C25-407E-8915-60C5652BC2A= A > + MODULE_TYPE =3D DXE_DRIVER > + VERSION_STRING =3D 1.0 > + ENTRY_POINT =3D SystemFirmwareUpdateMainDxe > + > +# > +# The following information is for reference only and not required by th= e build > tools. > +# > +# VALID_ARCHITECTURES =3D X64 > +# > + > +[Sources] > + SystemFirmwareDxe.h > + SystemFirmwareCommonDxe.c > + SystemFirmwareUpdateDxe.c > + ParseConfigProfile.c > + > +[Packages] > + MdePkg/MdePkg.dec > + MdeModulePkg/MdeModulePkg.dec > + VanGoghCommonPkg/AmdCommonPkg.dec > + SignedCapsulePkg/SignedCapsulePkg.dec > + ChachaniBoardPkg/Project.dec > + AgesaPublic/AgesaPublic.dec > + > +[LibraryClasses] > + BaseLib > + UefiLib > + BaseMemoryLib > + DebugLib > + PcdLib > + MemoryAllocationLib > + UefiBootServicesTableLib > + HobLib > + UefiRuntimeServicesTableLib > + UefiDriverEntryPoint > + DxeServicesLib > + EdkiiSystemCapsuleLib > + PlatformFlashAccessLib > + IniParsingLib > + PrintLib > + > +[Pcd] > + > gEfiMdeModulePkgTokenSpaceGuid.PcdSystemFmpCapsuleImageTypeIdGuid > ## CONSUMES > + gEfiSignedCapsulePkgTokenSpaceGuid.PcdEdkiiSystemFirmwareFileGuid > ## CONSUMES > + > gEfiSignedCapsulePkgTokenSpaceGuid.PcdEdkiiSystemFirmwareImageDescript > or ## CONSUMES > + gPlatformPkgTokenSpaceGuid.PcdFlashAreaBaseAddress = ## > CONSUMES > + gPlatformPkgTokenSpaceGuid.PcdFlashAreaSize = ## > CONSUMES > + gPlatformPkgTokenSpaceGuid.PcdFlashAbImageSlotDefaultPriority > ## CONSUMES > + > +[Guids] > + gOtaCapsuleUpdateGuid > + gABSupportUpdateIshGuid > + > +[Protocols] > + gEfiFirmwareManagementProtocolGuid ## PRODUCES > + > +[Depex] > + gEfiVariableArchProtocolGuid > + > +[UserExtensions.TianoCore."ExtraFiles"] > + SystemFirmwareUpdateDxeExtra.uni > + > diff --git > a/Platform/AMD/VanGoghBoard/Override/edk2/SignedCapsulePkg/Universal > /SystemFirmwareUpdate/SystemFirmwareUpdateDxe.uni > b/Platform/AMD/VanGoghBoard/Override/edk2/SignedCapsulePkg/Universa > l/SystemFirmwareUpdate/SystemFirmwareUpdateDxe.uni > new file mode 100644 > index 0000000000..e6bd18b249 > --- /dev/null > +++ > b/Platform/AMD/VanGoghBoard/Override/edk2/SignedCapsulePkg/Universa > l/SystemFirmwareUpdate/SystemFirmwareUpdateDxe.uni > @@ -0,0 +1,15 @@ > +// /** @file > +// SystemFirmware FMP update driver. > +// > +// Produce FMP instance to update system firmware. > +// > +// Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<= BR> > +// Copyright (c) 2016, Intel Corporation. All rights reserved.
> +// > +// SPDX-License-Identifier: BSD-2-Clause-Patent > +// > +// **/ > + > +#string STR_MODULE_ABSTRACT #language en-US "SystemFirmware > FMP update driver." > + > +#string STR_MODULE_DESCRIPTION #language en-US "Produce FMP > instance to update system firmware." > diff --git > a/Platform/AMD/VanGoghBoard/Override/edk2/SignedCapsulePkg/Universal > /SystemFirmwareUpdate/SystemFirmwareUpdateDxeExtra.uni > b/Platform/AMD/VanGoghBoard/Override/edk2/SignedCapsulePkg/Universa > l/SystemFirmwareUpdate/SystemFirmwareUpdateDxeExtra.uni > new file mode 100644 > index 0000000000..c549f017a4 > --- /dev/null > +++ > b/Platform/AMD/VanGoghBoard/Override/edk2/SignedCapsulePkg/Universa > l/SystemFirmwareUpdate/SystemFirmwareUpdateDxeExtra.uni > @@ -0,0 +1,15 @@ > +// /** @file > +// SystemFirmwareUpdateDxeExtra Localized Strings and Content > +// > +// Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<= BR> > +// Copyright (c) 2016, Intel Corporation. All rights reserved.
> +// > +// SPDX-License-Identifier: BSD-2-Clause-Patent > +// > +// **/ > + > +#string STR_PROPERTIES_MODULE_NAME > +#language en-US > +"SystemFirmwareUpdate DXE Driver" > + > + > -- > 2.31.1 -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#114566): https://edk2.groups.io/g/devel/message/114566 Mute This Topic: https://groups.io/mt/103971411/7686176 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-