From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: mx.groups.io; dkim=missing; spf=pass (domain: hpe.com, ip: 148.163.147.86, mailfrom: prvs=0151623386=gilbert.chen@hpe.com) Received: from mx0a-002e3701.pphosted.com (mx0a-002e3701.pphosted.com [148.163.147.86]) by groups.io with SMTP; Wed, 04 Sep 2019 18:25:05 -0700 Received: from pps.filterd (m0134421.ppops.net [127.0.0.1]) by mx0b-002e3701.pphosted.com (8.16.0.42/8.16.0.42) with SMTP id x851LUjJ012543 for ; Thu, 5 Sep 2019 01:25:04 GMT Received: from g9t5008.houston.hpe.com (g9t5008.houston.hpe.com [15.241.48.72]) by mx0b-002e3701.pphosted.com with ESMTP id 2utc41weex-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT) for ; Thu, 05 Sep 2019 01:25:03 +0000 Received: from G1W8108.americas.hpqcorp.net (g1w8108.austin.hp.com [16.193.72.60]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-SHA384 (256/256 bits)) (No client certificate requested) by g9t5008.houston.hpe.com (Postfix) with ESMTPS id F068C56 for ; Thu, 5 Sep 2019 01:25:02 +0000 (UTC) Received: from G4W9120.americas.hpqcorp.net (2002:10d2:150f::10d2:150f) by G1W8108.americas.hpqcorp.net (2002:10c1:483c::10c1:483c) with Microsoft SMTP Server (TLS) id 15.0.1367.3; Thu, 5 Sep 2019 01:25:02 +0000 Received: from NAM02-BL2-obe.outbound.protection.outlook.com (15.241.52.12) by G4W9120.americas.hpqcorp.net (16.210.21.15) with Microsoft SMTP Server (TLS) id 15.0.1367.3 via Frontend Transport; Thu, 5 Sep 2019 01:25:02 +0000 Received: from TU4PR8401MB1056.NAMPRD84.PROD.OUTLOOK.COM (10.169.47.148) by TU4PR8401MB1294.NAMPRD84.PROD.OUTLOOK.COM (10.169.48.146) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.2220.21; Thu, 5 Sep 2019 01:24:59 +0000 Received: from TU4PR8401MB1056.NAMPRD84.PROD.OUTLOOK.COM ([fe80::cc02:a574:b9e3:cf1e]) by TU4PR8401MB1056.NAMPRD84.PROD.OUTLOOK.COM ([fe80::cc02:a574:b9e3:cf1e%8]) with mapi id 15.20.2220.022; Thu, 5 Sep 2019 01:24:59 +0000 From: "Gilbert Chen" To: "devel@edk2.groups.io" Subject: [PATCH 11/15] [platforms/devel-riscv-v2]: U500Pkg/RamFvbServiceruntimeDxe: FVB driver for EFI variable. Thread-Topic: [PATCH 11/15] [platforms/devel-riscv-v2]: U500Pkg/RamFvbServiceruntimeDxe: FVB driver for EFI variable. Thread-Index: AdVjiLgjQ0nlHgtLRQG/gd2bEOQshg== Date: Thu, 5 Sep 2019 01:24:59 +0000 Message-ID: Accept-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-originating-ip: [16.242.247.133] x-ms-publictraffictype: Email x-ms-office365-filtering-correlation-id: dea22429-697e-4f48-e0ac-08d7319fde71 x-ms-office365-filtering-ht: Tenant x-microsoft-antispam: BCL:0;PCL:0;RULEID:(2390118)(7020095)(4652040)(8989299)(4534185)(4627221)(201703031133081)(201702281549075)(8990200)(5600166)(711020)(4605104)(1401327)(4618075)(2017052603328)(7193020);SRVR:TU4PR8401MB1294; x-ms-traffictypediagnostic: TU4PR8401MB1294: x-ms-exchange-purlcount: 1 x-microsoft-antispam-prvs: x-ms-oob-tlc-oobclassifiers: OLM:10000; x-forefront-prvs: 015114592F x-forefront-antispam-report: SFV:NSPM;SFS:(10019020)(1496009)(346002)(136003)(376002)(39860400002)(396003)(366004)(189003)(199004)(53376002)(55016002)(2501003)(52536014)(305945005)(7736002)(53946003)(14444005)(256004)(486006)(478600001)(9686003)(53936002)(16799955002)(66556008)(25786009)(66446008)(5640700003)(64756008)(99286004)(66476007)(5660300002)(316002)(66946007)(6306002)(6436002)(8936002)(74316002)(81166006)(1730700003)(966005)(76116006)(81156014)(186003)(30864003)(6506007)(15188155005)(3846002)(6116002)(102836004)(476003)(8676002)(2906002)(19627235002)(33656002)(66066001)(14454004)(26005)(71200400001)(6916009)(7696005)(2351001)(71190400001)(86362001)(569006);DIR:OUT;SFP:1102;SCL:1;SRVR:TU4PR8401MB1294;H:TU4PR8401MB1056.NAMPRD84.PROD.OUTLOOK.COM;FPR:;SPF:None;LANG:en;PTR:InfoNoRecords;MX:1;A:1; received-spf: None (protection.outlook.com: hpe.com does not designate permitted sender hosts) x-ms-exchange-senderadcheck: 1 x-microsoft-antispam-message-info: gaJc2GqAn1FrsmnJ27yJaZyWqp3jRagHJmJODM2bx0Qtx37woJ5NdnqcgCatqU4PoSY2FZ4GgvHHUxbs6qFOf1M8TRF42sFuHWehY4P80Ee3C/vMUb68qZWh0cs0IzwA4SZGevmIPY4sJZuZhvcWrgrW/CTiMU53cX0jc8y4JIQ11AAjdNrbCKuxqdcqdati6NDd218D80mSWB9lSZE6bmuGxtL4m7StczhZURXL6l+JJKHsaZPjJvZS8gB8GHXZFRzwbdTXt8Tl1nzFvtcAXqRbnqqmxcwQfIgRoyyHOjUws6nmmUnkUhmnyutTRmOoQbxMmOf3wJ4ZXkh55Jsx1HM5rNQ3/e5XoX3BZmhY+vaKSXyhlOFxnt3z1WpbQvVPInD59Mv9nwfKsGJePhZzuqhLR9tWZviA8U7HFbMkE58= x-ms-exchange-transport-forked: True arc-seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=UBIQWNF6p9ITIcXEV5ehgVDJ1Vb0p4oqb+9Wby4SrqS28n/YsvkI3SQs7Y1pev4c8LFsWuIkwCKFtMQrSsuUMIXOVH2eLYYuTpWMApyhI0TACbz2XySHlguHq/eMP+qMMr57FmxgQG0X3MjUDOKKzr/pkXBV3+mnmPbwPfTOX/VK1GWjq92lVK8riakam1u4x7ofnipa09ugBbiX9syNSDEgNZmwjmTUWHTRs/6PlbV/nS+ZCCxy3Z61e+XSDPWNaSwsBHpueSaTp5mZZDSvapeZrxVd1NTm2aDo1UFpYchVLWMhE9ZPOGXE4E2wI6NpBduo6i7v3o4D0mdMPwB09A== arc-message-signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=VJL0gtnQ1DbUSmMRsLYg7uzM8oFpgT1aDlNRv7dhYOA=; b=cKzZZWD7T/g3IGpNWOVShqaYuEbF3lYB4cGnBXtN8p/HErq1sJR0UwMiZ5hh1CwprXmWUcgTQprQjA0eIASijKVKcm18v7wXXZnkIbiWYFyEES4W0A1wKyrx2ZxKUcbqxsU+dHITBojRq9OnNRHnYADQjKz9UnMG+pldEG2M58JECuSww3TiYaD5n5KVO4xJ2U5FcOt3d7Odasygg9BGJzDy7gyDaGGRVBdKabA7g3jQotSncbVZ/uoHGfC5WtCW+LWFE5L03oggDj2ixdNp8usFnY+/Y9BsFdKWms7XJhm97uYY0XeiKtvvVm5lkRdYouvPtIdpKyDFsAMIyIJamA== arc-authentication-results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=hpe.com; dmarc=pass action=none header.from=hpe.com; dkim=pass header.d=hpe.com; arc=none x-ms-exchange-crosstenant-network-message-id: dea22429-697e-4f48-e0ac-08d7319fde71 x-ms-exchange-crosstenant-originalarrivaltime: 05 Sep 2019 01:24:59.5981 (UTC) x-ms-exchange-crosstenant-fromentityheader: Hosted x-ms-exchange-crosstenant-id: 105b2061-b669-4b31-92ac-24d304d195dc x-ms-exchange-crosstenant-mailboxtype: HOSTED x-ms-exchange-crosstenant-userprincipalname: iiZNvp+t1V+5uegM4i0Pkk6bVK4lAlydOXdnCY77sMucsUpruIIKpqfDfGM2IkvhQ0zdGH+/BZWIi68RzHuykQ== x-ms-exchange-transport-crosstenantheadersstamped: TU4PR8401MB1294 x-originatororg: hpe.com X-Proofpoint-UnRewURL: 0 URL was un-rewritten MIME-Version: 1.0 X-HPE-SCL: -1 X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.70,1.0.8 definitions=2019-09-05_01:2019-09-04,2019-09-05 signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 bulkscore=0 adultscore=0 phishscore=0 spamscore=0 lowpriorityscore=0 impostorscore=0 suspectscore=0 mlxlogscore=999 clxscore=1015 mlxscore=0 malwarescore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-1906280000 definitions=main-1909050012 Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Firmware Volume Block driver instance for ram based EFI variable on U500 pl= atform. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Gilbert Chen --- .../Dxe/RamFvbServicesRuntimeDxe/FvbInfo.c | 133 +++ .../FvbServicesRuntimeDxe.inf | 88 ++ .../Dxe/RamFvbServicesRuntimeDxe/FwBlockService.c | 1129 ++++++++++++++++= ++++ .../Dxe/RamFvbServicesRuntimeDxe/FwBlockService.h | 193 ++++ .../RamFvbServicesRuntimeDxe/FwBlockServiceDxe.c | 156 +++ .../Dxe/RamFvbServicesRuntimeDxe/RamFlash.c | 151 +++ .../Dxe/RamFvbServicesRuntimeDxe/RamFlash.h | 92 ++ .../Dxe/RamFvbServicesRuntimeDxe/RamFlashDxe.c | 26 + 8 files changed, 1968 insertions(+) create mode 100644 Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/RamFvbServi= cesRuntimeDxe/FvbInfo.c create mode 100644 Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/RamFvbServi= cesRuntimeDxe/FvbServicesRuntimeDxe.inf create mode 100644 Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/RamFvbServi= cesRuntimeDxe/FwBlockService.c create mode 100644 Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/RamFvbServi= cesRuntimeDxe/FwBlockService.h create mode 100644 Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/RamFvbServi= cesRuntimeDxe/FwBlockServiceDxe.c create mode 100644 Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/RamFvbServi= cesRuntimeDxe/RamFlash.c create mode 100644 Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/RamFvbServi= cesRuntimeDxe/RamFlash.h create mode 100644 Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/RamFvbServi= cesRuntimeDxe/RamFlashDxe.c diff --git a/Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/RamFvbServicesRunt= imeDxe/FvbInfo.c b/Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/RamFvbServic= esRuntimeDxe/FvbInfo.c new file mode 100644 index 0000000..bfed741 --- /dev/null +++ b/Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/RamFvbServicesRuntimeDxe/= FvbInfo.c @@ -0,0 +1,133 @@ +/**@file + + Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All right= s reserved.
+ Copyright (c) 2006, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials are licensed and made availa= ble + 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 IMP= LIED. + + Module Name: + + FvbInfo.c + + Abstract: + + Defines data structure that is the volume header found.These data is i= ntent + to decouple FVB driver with FV header. + +**/ + +// +// The package level header files this module uses +// +#include + +// +// The protocols, PPI and GUID defintions for this module +// +#include +// +// The Library classes this module consumes +// +#include +#include + +typedef struct { + UINT64 FvLength; + EFI_FIRMWARE_VOLUME_HEADER FvbInfo; + // + // EFI_FV_BLOCK_MAP_ENTRY ExtraBlockMap[n];//n=3D0 + // + EFI_FV_BLOCK_MAP_ENTRY End[1]; +} EFI_FVB_MEDIA_INFO; + +EFI_FVB_MEDIA_INFO mPlatformFvbMediaInfo[] =3D { + // + // Systen NvStorage FVB + // + { + FixedPcdGet32 (PcdFlashNvStorageVariableSize) + + FixedPcdGet32 (PcdFlashNvStorageFtwWorkingSize) + + FixedPcdGet32 (PcdFlashNvStorageFtwSpareSize), + { + { + 0, + }, // ZeroVector[16] + EFI_SYSTEM_NV_DATA_FV_GUID, + FixedPcdGet32 (PcdFlashNvStorageVariableSize) + + FixedPcdGet32 (PcdFlashNvStorageFtwWorkingSize) + + FixedPcdGet32 (PcdFlashNvStorageFtwSpareSize), + EFI_FVH_SIGNATURE, + EFI_FVB2_MEMORY_MAPPED | + EFI_FVB2_READ_ENABLED_CAP | + EFI_FVB2_READ_STATUS | + EFI_FVB2_WRITE_ENABLED_CAP | + EFI_FVB2_WRITE_STATUS | + EFI_FVB2_ERASE_POLARITY | + EFI_FVB2_ALIGNMENT_16, + sizeof (EFI_FIRMWARE_VOLUME_HEADER) + sizeof (EFI_FV_BLOCK_MAP_ENTRY= ), + 0, // CheckSum + 0, // ExtHeaderOffset + { + 0, + }, // Reserved[1] + 2, // Revision + { + { + (FixedPcdGet32 (PcdFlashNvStorageVariableSize) + + FixedPcdGet32 (PcdFlashNvStorageFtwWorkingSize) + + FixedPcdGet32 (PcdFlashNvStorageFtwSpareSize)) / + FixedPcdGet32 (PcdVariableFdBlockSize), + FixedPcdGet32 (PcdVariableFdBlockSize), + } + } // BlockMap[1] + }, + { + { + 0, + 0 + } + } // End[1] + } +}; + +EFI_STATUS +GetFvbInfo ( + IN UINT64 FvLength, + OUT EFI_FIRMWARE_VOLUME_HEADER **FvbInfo + ) +{ + STATIC BOOLEAN Checksummed =3D FALSE; + UINTN Index; + + if (!Checksummed) { + for (Index =3D 0; + Index < sizeof (mPlatformFvbMediaInfo) / sizeof (EFI_FVB_MEDIA_IN= FO); + Index +=3D 1) { + UINT16 Checksum; + mPlatformFvbMediaInfo[Index].FvbInfo.Checksum =3D 0; + Checksum =3D CalculateCheckSum16 ( + (UINT16*) &mPlatformFvbMediaInfo[Index].FvbInfo, + mPlatformFvbMediaInfo[Index].FvbInfo.HeaderLength + ); + mPlatformFvbMediaInfo[Index].FvbInfo.Checksum =3D Checksum; + } + Checksummed =3D TRUE; + } + + for (Index =3D 0; + Index < sizeof (mPlatformFvbMediaInfo) / sizeof (EFI_FVB_MEDIA_INFO= ); + Index +=3D 1) { + if (mPlatformFvbMediaInfo[Index].FvLength =3D=3D FvLength) { + *FvbInfo =3D &mPlatformFvbMediaInfo[Index].FvbInfo; + return EFI_SUCCESS; + } + } + + return EFI_NOT_FOUND; +} diff --git a/Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/RamFvbServicesRunt= imeDxe/FvbServicesRuntimeDxe.inf b/Platform/RiscV/SiFive/U500Pkg/Universal/= Dxe/RamFvbServicesRuntimeDxe/FvbServicesRuntimeDxe.inf new file mode 100644 index 0000000..e2fba24 --- /dev/null +++ b/Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/RamFvbServicesRuntimeDxe/= FvbServicesRuntimeDxe.inf @@ -0,0 +1,88 @@ +## @file +# Component description file for RAM Flash Fimware Volume Block DXE driver +# module. +# +# This DXE runtime driver implements and produces the Fimware Volue Block +# Protocol for a RAM flash device. +# +# Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All righ= ts reserved.
+# Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.
+# +# This program and the accompanying materials are licensed and made avail= able +# 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. +# +## + +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D FvbServicesRuntimeDxe + FILE_GUID =3D B04036D3-4C60-43D6-9850-0FCC090FF054 + MODULE_TYPE =3D DXE_RUNTIME_DRIVER + VERSION_STRING =3D 1.0 + ENTRY_POINT =3D FvbInitialize + +# +# The following information is for reference only and not required by the = build +# tools. +# +# VALID_ARCHITECTURES =3D IA32 X64 +# + +[Sources] + FvbInfo.c + FwBlockService.c + FwBlockServiceDxe.c + RamFlash.c + RamFlashDxe.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + Platform/RiscV/RiscVPlatformPkg.dec + +[LibraryClasses] + BaseLib + BaseMemoryLib + DebugLib + DevicePathLib + DxeServicesTableLib + MemoryAllocationLib + PcdLib + UefiBootServicesTableLib + UefiDriverEntryPoint + UefiRuntimeLib + +[Guids] + gEfiEventVirtualAddressChangeGuid # ALWAYS_CONSUMED + # gEfiEventVirtualAddressChangeGuid # Create Event: EVENT_GROUP_GUID + +[Protocols] + gEfiFirmwareVolumeBlockProtocolGuid # PROTOCOL SOMETIMES_PRODU= CED + gEfiDevicePathProtocolGuid # PROTOCOL SOMETIMES_PRODU= CED + +[FixedPcd] + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize + + gUefiRiscVPlatformPkgTokenSpaceGuid.PcdPlatformFlashNvStorageVariableBase + gUefiRiscVPlatformPkgTokenSpaceGuid.PcdPlatformFlashNvStorageFtwWorkingB= ase + gUefiRiscVPlatformPkgTokenSpaceGuid.PcdPlatformFlashNvStorageFtwSpareBase + gUefiRiscVPlatformPkgTokenSpaceGuid.PcdVariableFdBaseAddress + gUefiRiscVPlatformPkgTokenSpaceGuid.PcdVariableFdSize + gUefiRiscVPlatformPkgTokenSpaceGuid.PcdVariableFdBlockSize + +[Pcd] + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase64 + +[Depex] + TRUE diff --git a/Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/RamFvbServicesRunt= imeDxe/FwBlockService.c b/Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/RamFv= bServicesRuntimeDxe/FwBlockService.c new file mode 100644 index 0000000..b1a01e7 --- /dev/null +++ b/Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/RamFvbServicesRuntimeDxe/= FwBlockService.c @@ -0,0 +1,1129 @@ +/**@file + + Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All right= s reserved.
+ Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials are licensed and made availa= ble + 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 IMP= LIED. + + Module Name: + + FWBlockService.c + + Abstract: + + Revision History + +**/ + +// +// The protocols, PPI and GUID defintions for this module +// +#include +#include + +// +// The Library classes this module consumes +// +#include +#include +#include +#include +#include +#include +#include + +#include "FwBlockService.h" +#include "RamFlash.h" + +#define EFI_FVB2_STATUS \ + (EFI_FVB2_READ_STATUS | EFI_FVB2_WRITE_STATUS | EFI_FVB2_LOCK_ST= ATUS) + +ESAL_FWB_GLOBAL *mFvbModuleGlobal; + +FV_MEMMAP_DEVICE_PATH mFvMemmapDevicePathTemplate =3D { + { + { + HARDWARE_DEVICE_PATH, + HW_MEMMAP_DP, + { + (UINT8)(sizeof (MEMMAP_DEVICE_PATH)), + (UINT8)(sizeof (MEMMAP_DEVICE_PATH) >> 8) + } + }, + EfiMemoryMappedIO, + (EFI_PHYSICAL_ADDRESS) 0, + (EFI_PHYSICAL_ADDRESS) 0, + }, + { + END_DEVICE_PATH_TYPE, + END_ENTIRE_DEVICE_PATH_SUBTYPE, + { + END_DEVICE_PATH_LENGTH, + 0 + } + } +}; + +FV_PIWG_DEVICE_PATH mFvPIWGDevicePathTemplate =3D { + { + { + MEDIA_DEVICE_PATH, + MEDIA_PIWG_FW_VOL_DP, + { + (UINT8)(sizeof (MEDIA_FW_VOL_DEVICE_PATH)), + (UINT8)(sizeof (MEDIA_FW_VOL_DEVICE_PATH) >> 8) + } + }, + { 0 } + }, + { + END_DEVICE_PATH_TYPE, + END_ENTIRE_DEVICE_PATH_SUBTYPE, + { + END_DEVICE_PATH_LENGTH, + 0 + } + } +}; + +EFI_FW_VOL_BLOCK_DEVICE mFvbDeviceTemplate =3D { + FVB_DEVICE_SIGNATURE, + NULL, + 0, + { + FvbProtocolGetAttributes, + FvbProtocolSetAttributes, + FvbProtocolGetPhysicalAddress, + FvbProtocolGetBlockSize, + FvbProtocolRead, + FvbProtocolWrite, + FvbProtocolEraseBlocks, + NULL + } +}; + + +EFI_STATUS +GetFvbInstance ( + IN UINTN Instance, + IN ESAL_FWB_GLOBAL *Global, + OUT EFI_FW_VOL_INSTANCE **FwhInstance + ) +/*++ + + Routine Description: + Retrieves the physical address of a memory mapped FV + + Arguments: + Instance - The FV instance whose base address is going to= be + returned + Global - Pointer to ESAL_FWB_GLOBAL that contains all + instance data + FwhInstance - The EFI_FW_VOL_INSTANCE fimrware instance stru= cture + + Returns: + EFI_SUCCESS - Successfully returns + EFI_INVALID_PARAMETER - Instance not found + +--*/ +{ + EFI_FW_VOL_INSTANCE *FwhRecord; + + *FwhInstance =3D NULL; + if (Instance >=3D Global->NumFv) { + return EFI_INVALID_PARAMETER; + } + // + // Find the right instance of the FVB private data + // + FwhRecord =3D Global->FvInstance; + while (Instance > 0) { + FwhRecord =3D (EFI_FW_VOL_INSTANCE *) + ( + (UINTN) ((UINT8 *) FwhRecord) + FwhRecord->VolumeHeader.HeaderLeng= th + + (sizeof (EFI_FW_VOL_INSTANCE) - sizeof (EFI_FIRMWARE_VOLUME_HEAD= ER)) + ); + Instance--; + } + + *FwhInstance =3D FwhRecord; + + return EFI_SUCCESS; +} + +EFI_STATUS +FvbGetPhysicalAddress ( + IN UINTN Instance, + OUT EFI_PHYSICAL_ADDRESS *Address, + IN ESAL_FWB_GLOBAL *Global + ) +/*++ + + Routine Description: + Retrieves the physical address of a memory mapped FV + + Arguments: + Instance - The FV instance whose base address is going to= be + returned + Address - Pointer to a caller allocated EFI_PHYSICAL_ADD= RESS + that on successful return, contains the base + address of the firmware volume. + Global - Pointer to ESAL_FWB_GLOBAL that contains all + instance data + + Returns: + EFI_SUCCESS - Successfully returns + EFI_INVALID_PARAMETER - Instance not found + +--*/ +{ + EFI_FW_VOL_INSTANCE *FwhInstance; + EFI_STATUS Status; + + // + // Find the right instance of the FVB private data + // + Status =3D GetFvbInstance (Instance, Global, &FwhInstance); + ASSERT_EFI_ERROR (Status); + *Address =3D FwhInstance->FvBase; + + return EFI_SUCCESS; +} + +EFI_STATUS +FvbGetVolumeAttributes ( + IN UINTN Instance, + OUT EFI_FVB_ATTRIBUTES_2 *Attributes, + IN ESAL_FWB_GLOBAL *Global + ) +/*++ + + Routine Description: + Retrieves attributes, insures positive polarity of attribute bits, ret= urns + resulting attributes in output parameter + + Arguments: + Instance - The FV instance whose attributes is going to be + returned + Attributes - Output buffer which contains attributes + Global - Pointer to ESAL_FWB_GLOBAL that contains all + instance data + + Returns: + EFI_SUCCESS - Successfully returns + EFI_INVALID_PARAMETER - Instance not found + +--*/ +{ + EFI_FW_VOL_INSTANCE *FwhInstance; + EFI_STATUS Status; + + // + // Find the right instance of the FVB private data + // + Status =3D GetFvbInstance (Instance, Global, &FwhInstance); + ASSERT_EFI_ERROR (Status); + *Attributes =3D FwhInstance->VolumeHeader.Attributes; + + return EFI_SUCCESS; +} + +EFI_STATUS +FvbGetLbaAddress ( + IN UINTN Instance, + IN EFI_LBA Lba, + OUT UINTN *LbaAddress, + OUT UINTN *LbaLength, + OUT UINTN *NumOfBlocks, + IN ESAL_FWB_GLOBAL *Global + ) +/*++ + + Routine Description: + Retrieves the starting address of an LBA in an FV + + Arguments: + Instance - The FV instance which the Lba belongs to + Lba - The logical block address + LbaAddress - On output, contains the physical starting addr= ess + of the Lba + LbaLength - On output, contains the length of the block + NumOfBlocks - A pointer to a caller allocated UINTN in which= the + number of consecutive blocks starting with Lba= is + returned. All blocks in this range have a size= of + BlockSize + Global - Pointer to ESAL_FWB_GLOBAL that contains all + instance data + + Returns: + EFI_SUCCESS - Successfully returns + EFI_INVALID_PARAMETER - Instance not found + +--*/ +{ + UINT32 NumBlocks; + UINT32 BlockLength; + UINTN Offset; + EFI_LBA StartLba; + EFI_LBA NextLba; + EFI_FW_VOL_INSTANCE *FwhInstance; + EFI_FV_BLOCK_MAP_ENTRY *BlockMap; + EFI_STATUS Status; + + // + // Find the right instance of the FVB private data + // + Status =3D GetFvbInstance (Instance, Global, &FwhInstance); + ASSERT_EFI_ERROR (Status); + + StartLba =3D 0; + Offset =3D 0; + BlockMap =3D &(FwhInstance->VolumeHeader.BlockMap[0]); + + // + // Parse the blockmap of the FV to find which map entry the Lba belongs = to + // + while (TRUE) { + NumBlocks =3D BlockMap->NumBlocks; + BlockLength =3D BlockMap->Length; + + if (NumBlocks =3D=3D 0 || BlockLength =3D=3D 0) { + return EFI_INVALID_PARAMETER; + } + + NextLba =3D StartLba + NumBlocks; + + // + // The map entry found + // + if (Lba >=3D StartLba && Lba < NextLba) { + Offset =3D Offset + (UINTN) MultU64x32 ((Lba - StartLba), BlockLengt= h); + if (LbaAddress !=3D NULL) { + *LbaAddress =3D FwhInstance->FvBase + Offset; + } + + if (LbaLength !=3D NULL) { + *LbaLength =3D BlockLength; + } + + if (NumOfBlocks !=3D NULL) { + *NumOfBlocks =3D (UINTN) (NextLba - Lba); + } + + return EFI_SUCCESS; + } + + StartLba =3D NextLba; + Offset =3D Offset + NumBlocks * BlockLength; + BlockMap++; + } +} + +EFI_STATUS +FvbSetVolumeAttributes ( + IN UINTN Instance, + IN OUT EFI_FVB_ATTRIBUTES_2 *Attributes, + IN ESAL_FWB_GLOBAL *Global + ) +/*++ + + Routine Description: + Modifies the current settings of the firmware volume according to the + input parameter, and returns the new setting of the volume + + Arguments: + Instance - The FV instance whose attributes is going to be + modified + Attributes - On input, it is a pointer to EFI_FVB_ATTRIBUTE= S_2 + containing the desired firmware volume setting= s. + On successful return, it contains the new sett= ings + of the firmware volume + Global - Pointer to ESAL_FWB_GLOBAL that contains all + instance data + + Returns: + EFI_SUCCESS - Successfully returns + EFI_ACCESS_DENIED - The volume setting is locked and cannot be mod= ified + EFI_INVALID_PARAMETER - Instance not found, or The attributes requeste= d are + in conflict with the capabilities as declared = in + the firmware volume header + +--*/ +{ + EFI_FW_VOL_INSTANCE *FwhInstance; + EFI_FVB_ATTRIBUTES_2 OldAttributes; + EFI_FVB_ATTRIBUTES_2 *AttribPtr; + UINT32 Capabilities; + UINT32 OldStatus; + UINT32 NewStatus; + EFI_STATUS Status; + EFI_FVB_ATTRIBUTES_2 UnchangedAttributes; + + // + // Find the right instance of the FVB private data + // + Status =3D GetFvbInstance (Instance, Global, &FwhInstance); + ASSERT_EFI_ERROR (Status); + + AttribPtr =3D + (EFI_FVB_ATTRIBUTES_2 *) &(FwhInstance->VolumeHeader.Attributes); + OldAttributes =3D *AttribPtr; + Capabilities =3D OldAttributes & (EFI_FVB2_READ_DISABLED_CAP | \ + EFI_FVB2_READ_ENABLED_CAP | \ + EFI_FVB2_WRITE_DISABLED_CAP | \ + EFI_FVB2_WRITE_ENABLED_CAP | \ + EFI_FVB2_LOCK_CAP \ + ); + OldStatus =3D OldAttributes & EFI_FVB2_STATUS; + NewStatus =3D *Attributes & EFI_FVB2_STATUS; + + UnchangedAttributes =3D EFI_FVB2_READ_DISABLED_CAP | \ + EFI_FVB2_READ_ENABLED_CAP | \ + EFI_FVB2_WRITE_DISABLED_CAP | \ + EFI_FVB2_WRITE_ENABLED_CAP | \ + EFI_FVB2_LOCK_CAP | \ + EFI_FVB2_STICKY_WRITE | \ + EFI_FVB2_MEMORY_MAPPED | \ + EFI_FVB2_ERASE_POLARITY | \ + EFI_FVB2_READ_LOCK_CAP | \ + EFI_FVB2_WRITE_LOCK_CAP | \ + EFI_FVB2_ALIGNMENT; + + // + // Some attributes of FV is read only can *not* be set + // + if ((OldAttributes & UnchangedAttributes) ^ + (*Attributes & UnchangedAttributes)) { + return EFI_INVALID_PARAMETER; + } + // + // If firmware volume is locked, no status bit can be updated + // + if (OldAttributes & EFI_FVB2_LOCK_STATUS) { + if (OldStatus ^ NewStatus) { + return EFI_ACCESS_DENIED; + } + } + // + // Test read disable + // + if ((Capabilities & EFI_FVB2_READ_DISABLED_CAP) =3D=3D 0) { + if ((NewStatus & EFI_FVB2_READ_STATUS) =3D=3D 0) { + return EFI_INVALID_PARAMETER; + } + } + // + // Test read enable + // + if ((Capabilities & EFI_FVB2_READ_ENABLED_CAP) =3D=3D 0) { + if (NewStatus & EFI_FVB2_READ_STATUS) { + return EFI_INVALID_PARAMETER; + } + } + // + // Test write disable + // + if ((Capabilities & EFI_FVB2_WRITE_DISABLED_CAP) =3D=3D 0) { + if ((NewStatus & EFI_FVB2_WRITE_STATUS) =3D=3D 0) { + return EFI_INVALID_PARAMETER; + } + } + // + // Test write enable + // + if ((Capabilities & EFI_FVB2_WRITE_ENABLED_CAP) =3D=3D 0) { + if (NewStatus & EFI_FVB2_WRITE_STATUS) { + return EFI_INVALID_PARAMETER; + } + } + // + // Test lock + // + if ((Capabilities & EFI_FVB2_LOCK_CAP) =3D=3D 0) { + if (NewStatus & EFI_FVB2_LOCK_STATUS) { + return EFI_INVALID_PARAMETER; + } + } + + *AttribPtr =3D (*AttribPtr) & (0xFFFFFFFF & (~EFI_FVB2_STATUS)); + *AttribPtr =3D (*AttribPtr) | NewStatus; + *Attributes =3D *AttribPtr; + + return EFI_SUCCESS; +} + +// +// FVB protocol APIs +// +EFI_STATUS +EFIAPI +FvbProtocolGetPhysicalAddress ( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, + OUT EFI_PHYSICAL_ADDRESS *Address + ) +/*++ + + Routine Description: + + Retrieves the physical address of the device. + + Arguments: + + This - Calling context + Address - Output buffer containing the address. + + Returns: + EFI_SUCCESS - Successfully returns + +--*/ +{ + EFI_FW_VOL_BLOCK_DEVICE *FvbDevice; + + FvbDevice =3D FVB_DEVICE_FROM_THIS (This); + + return FvbGetPhysicalAddress (FvbDevice->Instance, Address, + mFvbModuleGlobal); +} + +EFI_STATUS +EFIAPI +FvbProtocolGetBlockSize ( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, + IN CONST EFI_LBA Lba, + OUT UINTN *BlockSize, + OUT UINTN *NumOfBlocks + ) +/*++ + + Routine Description: + Retrieve the size of a logical block + + Arguments: + This - Calling context + Lba - Indicates which block to return the size for. + BlockSize - A pointer to a caller allocated UINTN in which + the size of the block is returned + NumOfBlocks - a pointer to a caller allocated UINTN in which= the + number of consecutive blocks starting with Lba= is + returned. All blocks in this range have a size= of + BlockSize + + Returns: + EFI_SUCCESS - The firmware volume was read successfully and + contents are in Buffer + +--*/ +{ + EFI_FW_VOL_BLOCK_DEVICE *FvbDevice; + + FvbDevice =3D FVB_DEVICE_FROM_THIS (This); + + return FvbGetLbaAddress ( + FvbDevice->Instance, + Lba, + NULL, + BlockSize, + NumOfBlocks, + mFvbModuleGlobal + ); +} + +EFI_STATUS +EFIAPI +FvbProtocolGetAttributes ( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, + OUT EFI_FVB_ATTRIBUTES_2 *Attributes + ) +/*++ + + Routine Description: + Retrieves Volume attributes. No polarity translations are done. + + Arguments: + This - Calling context + Attributes - output buffer which contains attributes + + Returns: + EFI_SUCCESS - Successfully returns + +--*/ +{ + EFI_FW_VOL_BLOCK_DEVICE *FvbDevice; + + FvbDevice =3D FVB_DEVICE_FROM_THIS (This); + + return FvbGetVolumeAttributes (FvbDevice->Instance, Attributes, + mFvbModuleGlobal); +} + +EFI_STATUS +EFIAPI +FvbProtocolSetAttributes ( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, + IN OUT EFI_FVB_ATTRIBUTES_2 *Attributes + ) +/*++ + + Routine Description: + Sets Volume attributes. No polarity translations are done. + + Arguments: + This - Calling context + Attributes - output buffer which contains attributes + + Returns: + EFI_SUCCESS - Successfully returns + +--*/ +{ + EFI_FW_VOL_BLOCK_DEVICE *FvbDevice; + + FvbDevice =3D FVB_DEVICE_FROM_THIS (This); + + return FvbSetVolumeAttributes (FvbDevice->Instance, Attributes, + mFvbModuleGlobal); +} + +EFI_STATUS +EFIAPI +FvbProtocolEraseBlocks ( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, + ... + ) +/*++ + + Routine Description: + + The EraseBlock() function erases one or more blocks as denoted by the + variable argument list. The entire parameter list of blocks must be + verified prior to erasing any blocks. If a block is requested that do= es + not exist within the associated firmware volume (it has a larger index= than + the last block of the firmware volume), the EraseBlock() function must + return EFI_INVALID_PARAMETER without modifying the contents of the fir= mware + volume. + + Arguments: + This - Calling context + ... - Starting LBA followed by Number of Lba to eras= e. + a -1 to terminate the list. + + Returns: + EFI_SUCCESS - The erase request was successfully completed + EFI_ACCESS_DENIED - The firmware volume is in the WriteDisabled st= ate + EFI_DEVICE_ERROR - The block device is not functioning correctly = and + could not be written. Firmware device may have= been + partially erased + +--*/ +{ + EFI_FW_VOL_BLOCK_DEVICE *FvbDevice; + EFI_FW_VOL_INSTANCE *FwhInstance; + UINTN NumOfBlocks; + VA_LIST args; + EFI_LBA StartingLba; + UINTN NumOfLba; + EFI_STATUS Status; + + FvbDevice =3D FVB_DEVICE_FROM_THIS (This); + + Status =3D GetFvbInstance (FvbDevice->Instance, mFvbModuleGlobal, + &FwhInstance); + ASSERT_EFI_ERROR (Status); + + NumOfBlocks =3D FwhInstance->NumOfBlocks; + + VA_START (args, This); + + do { + StartingLba =3D VA_ARG (args, EFI_LBA); + if (StartingLba =3D=3D EFI_LBA_LIST_TERMINATOR) { + break; + } + + NumOfLba =3D VA_ARG (args, UINT32); + + // + // Check input parameters + // + if ((NumOfLba =3D=3D 0) || ((StartingLba + NumOfLba) > NumOfBlocks)) { + VA_END (args); + return EFI_INVALID_PARAMETER; + } + } while (1); + + VA_END (args); + + VA_START (args, This); + do { + StartingLba =3D VA_ARG (args, EFI_LBA); + if (StartingLba =3D=3D EFI_LBA_LIST_TERMINATOR) { + break; + } + + NumOfLba =3D VA_ARG (args, UINT32); + + while (NumOfLba > 0) { + Status =3D RamFlashEraseBlock (StartingLba); + if (EFI_ERROR (Status)) { + VA_END (args); + return Status; + } + + StartingLba++; + NumOfLba--; + } + + } while (1); + + VA_END (args); + + return EFI_SUCCESS; +} + +EFI_STATUS +EFIAPI +FvbProtocolWrite ( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, + IN EFI_LBA Lba, + IN UINTN Offset, + IN OUT UINTN *NumBytes, + IN UINT8 *Buffer + ) +/*++ + + Routine Description: + + Writes data beginning at Lba:Offset from FV. The write terminates eith= er + when *NumBytes of data have been written, or when a block boundary is + reached. *NumBytes is updated to reflect the actual number of bytes + written. The write opertion does not include erase. This routine will + attempt to write only the specified bytes. If the writes do not stick, + it will return an error. + + Arguments: + This - Calling context + Lba - Block in which to begin write + Offset - Offset in the block at which to begin write + NumBytes - On input, indicates the requested write size. = On + output, indicates the actual number of bytes + written + Buffer - Buffer containing source data for the write. + + Returns: + EFI_SUCCESS - The firmware volume was written successfully + EFI_BAD_BUFFER_SIZE - Write attempted across a LBA boundary. On outp= ut, + NumBytes contains the total number of bytes + actually written + EFI_ACCESS_DENIED - The firmware volume is in the WriteDisabled st= ate + EFI_DEVICE_ERROR - The block device is not functioning correctly = and + could not be written + EFI_INVALID_PARAMETER - NumBytes or Buffer are NULL + +--*/ +{ + return RamFlashWrite ((EFI_LBA)Lba, (UINTN)Offset, NumBytes, + (UINT8 *)Buffer); +} + +EFI_STATUS +EFIAPI +FvbProtocolRead ( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, + IN CONST EFI_LBA Lba, + IN CONST UINTN Offset, + IN OUT UINTN *NumBytes, + IN UINT8 *Buffer + ) +/*++ + + Routine Description: + + Reads data beginning at Lba:Offset from FV. The Read terminates either + when *NumBytes of data have been read, or when a block boundary is + reached. *NumBytes is updated to reflect the actual number of bytes + written. The write opertion does not include erase. This routine will + attempt to write only the specified bytes. If the writes do not stick, + it will return an error. + + Arguments: + This - Calling context + Lba - Block in which to begin Read + Offset - Offset in the block at which to begin Read + NumBytes - On input, indicates the requested write size. = On + output, indicates the actual number of bytes R= ead + Buffer - Buffer containing source data for the Read. + + Returns: + EFI_SUCCESS - The firmware volume was read successfully and + contents are in Buffer + EFI_BAD_BUFFER_SIZE - Read attempted across a LBA boundary. On outpu= t, + NumBytes contains the total number of bytes + returned in Buffer + EFI_ACCESS_DENIED - The firmware volume is in the ReadDisabled sta= te + EFI_DEVICE_ERROR - The block device is not functioning correctly = and + could not be read + EFI_INVALID_PARAMETER - NumBytes or Buffer are NULL + +--*/ +{ + return RamFlashRead ((EFI_LBA)Lba, (UINTN)Offset, NumBytes, + (UINT8 *)Buffer); +} + +EFI_STATUS +ValidateFvHeader ( + EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader + ) +/*++ + + Routine Description: + Check the integrity of firmware volume header + + Arguments: + FwVolHeader - A pointer to a firmware volume header + + Returns: + EFI_SUCCESS - The firmware volume is consistent + EFI_NOT_FOUND - The firmware volume has corrupted. So it is no= t an + FV + +--*/ +{ + UINT16 Checksum; + + // + // Verify the header revision, header signature, length + // Length of FvBlock cannot be 2**64-1 + // HeaderLength cannot be an odd number + // + if ((FwVolHeader->Revision !=3D EFI_FVH_REVISION) || + (FwVolHeader->Signature !=3D EFI_FVH_SIGNATURE) || + (FwVolHeader->FvLength =3D=3D ((UINTN) -1)) || + ((FwVolHeader->HeaderLength & 0x01) !=3D 0) + ) { + return EFI_NOT_FOUND; + } + + // + // Verify the header checksum + // + + Checksum =3D CalculateSum16 ((UINT16 *) FwVolHeader, + FwVolHeader->HeaderLength); + if (Checksum !=3D 0) { + UINT16 Expected; + + Expected =3D + (UINT16) (((UINTN) FwVolHeader->Checksum + 0x10000 - Checksum) & 0xf= fff); + + DEBUG ((EFI_D_INFO, "FV@%p Checksum is 0x%x, expected 0x%x\n", + FwVolHeader, FwVolHeader->Checksum, Expected)); + return EFI_NOT_FOUND; + } + + return EFI_SUCCESS; +} + +STATIC +EFI_STATUS +MarkMemoryRangeForRuntimeAccess ( + EFI_PHYSICAL_ADDRESS BaseAddress, + UINTN Length + ) +{ + EFI_STATUS Status; + + // + // Mark flash region as runtime memory + // + Status =3D gDS->RemoveMemorySpace ( + BaseAddress, + Length + ); + + Status =3D gDS->AddMemorySpace ( + EfiGcdMemoryTypeSystemMemory, + BaseAddress, + Length, + EFI_MEMORY_UC | EFI_MEMORY_RUNTIME + ); + ASSERT_EFI_ERROR (Status); + + Status =3D gBS->AllocatePages ( + AllocateAddress, + EfiRuntimeServicesData, + EFI_SIZE_TO_PAGES (Length), + &BaseAddress + ); + ASSERT_EFI_ERROR (Status); + + return Status; +} + +STATIC +EFI_STATUS +InitializeVariableFvHeader ( + VOID + ) +{ + EFI_STATUS Status; + EFI_FIRMWARE_VOLUME_HEADER *GoodFwVolHeader; + EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader; + UINTN Length; + UINTN WriteLength; + UINTN BlockSize; + + FwVolHeader =3D + (EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) + PcdGet32 (PcdPlatformFlashNvStorageVariableBase); + + Length =3D + (FixedPcdGet32 (PcdFlashNvStorageVariableSize) + + FixedPcdGet32 (PcdFlashNvStorageFtwWorkingSize) + + FixedPcdGet32 (PcdFlashNvStorageFtwSpareSize)); + + BlockSize =3D PcdGet32 (PcdVariableFdBlockSize); + + Status =3D ValidateFvHeader (FwVolHeader); + if (!EFI_ERROR (Status)) { + DEBUG ((EFI_D_INFO, "ValidateFvHeader() return ok\n")); + if (FwVolHeader->FvLength !=3D Length || + FwVolHeader->BlockMap[0].Length !=3D BlockSize) { + Status =3D EFI_VOLUME_CORRUPTED; + DEBUG ((EFI_D_INFO, "FwVolHeader->FvLength(%x) !=3D Length(%x) || FwV= olHeader->BlockMap[0].Length(%x) !=3D BlockSize(%x)\n", FwVolHeader->FvLeng= th, Length, FwVolHeader->BlockMap[0].Length, BlockSize)); + } + } + else { + DEBUG ((EFI_D_INFO, "ValidateFvHeader() return failed\n")); + } + if (EFI_ERROR (Status)) { + UINTN Offset; + UINTN Start; + + DEBUG ((EFI_D_INFO, + "Variable FV header is not valid. It will be reinitialized.\n")); + + // + // Get FvbInfo to provide in FwhInstance. + // + Status =3D GetFvbInfo (Length, &GoodFwVolHeader); + ASSERT (!EFI_ERROR (Status)); + + Start =3D (UINTN)(UINT8*) FwVolHeader - PcdGet32 (PcdVariableFdBaseAdd= ress); + ASSERT (Start % BlockSize =3D=3D 0 && Length % BlockSize =3D=3D 0); + ASSERT (GoodFwVolHeader->HeaderLength <=3D BlockSize); + + // + // Erase all the blocks + // + for (Offset =3D Start; Offset < Start + Length; Offset +=3D BlockSize)= { + Status =3D RamFlashEraseBlock (Offset / BlockSize); + ASSERT_EFI_ERROR (Status); + } + + // + // Write good FV header + // + WriteLength =3D GoodFwVolHeader->HeaderLength; + Status =3D RamFlashWrite ( + Start / BlockSize, + 0, + &WriteLength, + (UINT8 *) GoodFwVolHeader); + ASSERT_EFI_ERROR (Status); + ASSERT (WriteLength =3D=3D GoodFwVolHeader->HeaderLength); + } + + return Status; +} + +EFI_STATUS +EFIAPI +FvbInitialize ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +/*++ + + Routine Description: + This function does common initialization for FVB services + + Arguments: + + Returns: + +--*/ +{ + EFI_STATUS Status; + EFI_FW_VOL_INSTANCE *FwhInstance; + EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader; + UINT32 BufferSize; + EFI_FV_BLOCK_MAP_ENTRY *PtrBlockMapEntry; + EFI_FW_VOL_BLOCK_DEVICE *FvbDevice; + UINT32 MaxLbaSize; + EFI_PHYSICAL_ADDRESS BaseAddress; + UINTN Length; + UINTN NumOfBlocks; + + if (EFI_ERROR (RamFlashInitialize ())) { + // + // Return an error so image will be unloaded + // + DEBUG ((EFI_D_INFO, + "RAM flash was not detected. Writable FVB is not being installed.\n"= )); + return EFI_WRITE_PROTECTED; + } + + // + // Allocate runtime services data for global variable, which contains + // the private data of all firmware volume block instances + // + mFvbModuleGlobal =3D AllocateRuntimePool (sizeof (ESAL_FWB_GLOBAL)); + ASSERT (mFvbModuleGlobal !=3D NULL); + + BaseAddress =3D (UINTN) PcdGet32 (PcdVariableFdBaseAddress); + Length =3D PcdGet32 (PcdVariableFdSize); + DEBUG ((EFI_D_INFO, "FvbInitialize(): BaseAddress: 0x%lx Length:0x%x\n",= BaseAddress, Length)); + Status =3D InitializeVariableFvHeader (); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_INFO, + "RAM Flash: Unable to initialize variable FV header\n")); + return EFI_WRITE_PROTECTED; + } + + FwVolHeader =3D (EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) BaseAddress; + Status =3D ValidateFvHeader (FwVolHeader); + if (EFI_ERROR (Status)) { + // + // Get FvbInfo + // + DEBUG ((EFI_D_INFO, "FvbInitialize(): ValidateFvHeader() return error(= %r)\n", Status)); + + Status =3D GetFvbInfo (Length, &FwVolHeader); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_INFO, "FvbInitialize(): GetFvbInfo (Length, &FwVolHead= er) return error(%r)\n", Status)); + return EFI_WRITE_PROTECTED; + } + } + + BufferSize =3D (sizeof (EFI_FW_VOL_INSTANCE) + + FwVolHeader->HeaderLength - + sizeof (EFI_FIRMWARE_VOLUME_HEADER) + ); + mFvbModuleGlobal->FvInstance =3D AllocateRuntimePool (BufferSize); + ASSERT (mFvbModuleGlobal->FvInstance !=3D NULL); + + FwhInstance =3D mFvbModuleGlobal->FvInstance; + + mFvbModuleGlobal->NumFv =3D 0; + MaxLbaSize =3D 0; + + FwVolHeader =3D + (EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) + PcdGet32 (PcdPlatformFlashNvStorageVariableBase); + + FwhInstance->FvBase =3D (UINTN) BaseAddress; + + CopyMem ((UINTN *) &(FwhInstance->VolumeHeader), (UINTN *) FwVolHeader, + FwVolHeader->HeaderLength); + FwVolHeader =3D &(FwhInstance->VolumeHeader); + + NumOfBlocks =3D 0; + + for (PtrBlockMapEntry =3D FwVolHeader->BlockMap; + PtrBlockMapEntry->NumBlocks !=3D 0; + PtrBlockMapEntry++) { + // + // Get the maximum size of a block. + // + if (MaxLbaSize < PtrBlockMapEntry->Length) { + MaxLbaSize =3D PtrBlockMapEntry->Length; + } + + NumOfBlocks =3D NumOfBlocks + PtrBlockMapEntry->NumBlocks; + } + + // + // The total number of blocks in the FV. + // + FwhInstance->NumOfBlocks =3D NumOfBlocks; + + // + // Add a FVB Protocol Instance + // + FvbDevice =3D AllocateRuntimePool (sizeof (EFI_FW_VOL_BLOCK_DEVICE)); + ASSERT (FvbDevice !=3D NULL); + + CopyMem (FvbDevice, &mFvbDeviceTemplate, sizeof (EFI_FW_VOL_BLOCK_DEVICE= )); + + FvbDevice->Instance =3D mFvbModuleGlobal->NumFv; + mFvbModuleGlobal->NumFv++; + + // + // Set up the devicepath + // + if (FwVolHeader->ExtHeaderOffset =3D=3D 0) { + FV_MEMMAP_DEVICE_PATH *FvMemmapDevicePath; + + // + // FV does not contains extension header, then produce MEMMAP_DEVICE_P= ATH + // + FvMemmapDevicePath =3D AllocateCopyPool (sizeof (FV_MEMMAP_DEVICE_PATH= ), + &mFvMemmapDevicePathTemplate); + FvMemmapDevicePath->MemMapDevPath.StartingAddress =3D BaseAddress; + FvMemmapDevicePath->MemMapDevPath.EndingAddress =3D + BaseAddress + FwVolHeader->FvLength - 1; + FvbDevice->DevicePath =3D (EFI_DEVICE_PATH_PROTOCOL *)FvMemmapDevicePa= th; + } else { + FV_PIWG_DEVICE_PATH *FvPiwgDevicePath; + + FvPiwgDevicePath =3D AllocateCopyPool (sizeof (FV_PIWG_DEVICE_PATH), + &mFvPIWGDevicePathTemplate); + CopyGuid ( + &FvPiwgDevicePath->FvDevPath.FvName, + (GUID *)(UINTN)(BaseAddress + FwVolHeader->ExtHeaderOffset) + ); + FvbDevice->DevicePath =3D (EFI_DEVICE_PATH_PROTOCOL *)FvPiwgDevicePath; + } + + // + // Module type specific hook. + // + InstallProtocolInterfaces (FvbDevice); + + MarkMemoryRangeForRuntimeAccess (BaseAddress, Length); + + // + // Set several PCD values to point to flash + // + PcdSet64 ( + PcdFlashNvStorageVariableBase64, + (UINTN) PcdGet32 (PcdPlatformFlashNvStorageVariableBase) + ); + PcdSet32 ( + PcdFlashNvStorageFtwWorkingBase, + PcdGet32 (PcdPlatformFlashNvStorageFtwWorkingBase) + ); + PcdSet32 ( + PcdFlashNvStorageFtwSpareBase, + PcdGet32 (PcdPlatformFlashNvStorageFtwSpareBase) + ); + + FwhInstance =3D (EFI_FW_VOL_INSTANCE *) + ( + (UINTN) ((UINT8 *) FwhInstance) + FwVolHeader->HeaderLength + + (sizeof (EFI_FW_VOL_INSTANCE) - sizeof (EFI_FIRMWARE_VOLUME_HEADER)) + ); + + // + // Module type specific hook. + // + InstallVirtualAddressChangeHandler (); + return EFI_SUCCESS; +} diff --git a/Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/RamFvbServicesRunt= imeDxe/FwBlockService.h b/Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/RamFv= bServicesRuntimeDxe/FwBlockService.h new file mode 100644 index 0000000..c6131be --- /dev/null +++ b/Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/RamFvbServicesRuntimeDxe/= FwBlockService.h @@ -0,0 +1,193 @@ +/**@file + + Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All right= s reserved.
+ Copyright (c) 2006, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials are licensed and made availa= ble + 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 IMP= LIED. + + Module Name: + + FwBlockService.h + + Abstract: + + Firmware volume block driver for Intel Firmware Hub (FWH) device + +**/ + +#ifndef _FW_BLOCK_SERVICE_H +#define _FW_BLOCK_SERVICE_H + +typedef struct { + UINTN FvBase; + UINTN NumOfBlocks; + EFI_FIRMWARE_VOLUME_HEADER VolumeHeader; +} EFI_FW_VOL_INSTANCE; + +typedef struct { + UINT32 NumFv; + EFI_FW_VOL_INSTANCE *FvInstance; +} ESAL_FWB_GLOBAL; + +extern ESAL_FWB_GLOBAL *mFvbModuleGlobal; + +// +// Fvb Protocol instance data +// +#define FVB_DEVICE_FROM_THIS(a) CR (a, EFI_FW_VOL_BLOCK_DEVICE, \ + FwVolBlockInstance, FVB_DEVICE_SIGNATURE) + +#define FVB_EXTEND_DEVICE_FROM_THIS(a) CR (a, EFI_FW_VOL_BLOCK_DEVICE, \ + FvbExtension, FVB_DEVICE_SIGNATUR= E) + +#define FVB_DEVICE_SIGNATURE SIGNATURE_32 ('F', 'V', 'B', 'N') + +typedef struct { + MEDIA_FW_VOL_DEVICE_PATH FvDevPath; + EFI_DEVICE_PATH_PROTOCOL EndDevPath; +} FV_PIWG_DEVICE_PATH; + +typedef struct { + MEMMAP_DEVICE_PATH MemMapDevPath; + EFI_DEVICE_PATH_PROTOCOL EndDevPath; +} FV_MEMMAP_DEVICE_PATH; + +typedef struct { + UINTN Signature; + EFI_DEVICE_PATH_PROTOCOL *DevicePath; + UINTN Instance; + EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL FwVolBlockInstance; +} EFI_FW_VOL_BLOCK_DEVICE; + +EFI_STATUS +GetFvbInfo ( + IN UINT64 FvLength, + OUT EFI_FIRMWARE_VOLUME_HEADER **FvbInfo + ); + +EFI_STATUS +FvbSetVolumeAttributes ( + IN UINTN Instance, + IN OUT EFI_FVB_ATTRIBUTES_2 *Attributes, + IN ESAL_FWB_GLOBAL *Global + ); + +EFI_STATUS +FvbGetVolumeAttributes ( + IN UINTN Instance, + OUT EFI_FVB_ATTRIBUTES_2 *Attributes, + IN ESAL_FWB_GLOBAL *Global + ); + +EFI_STATUS +FvbGetPhysicalAddress ( + IN UINTN Instance, + OUT EFI_PHYSICAL_ADDRESS *Address, + IN ESAL_FWB_GLOBAL *Global + ); + +EFI_STATUS +EFIAPI +FvbInitialize ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ); + + +VOID +EFIAPI +FvbClassAddressChangeEvent ( + IN EFI_EVENT Event, + IN VOID *Context + ); + +EFI_STATUS +FvbGetLbaAddress ( + IN UINTN Instance, + IN EFI_LBA Lba, + OUT UINTN *LbaAddress, + OUT UINTN *LbaLength, + OUT UINTN *NumOfBlocks, + IN ESAL_FWB_GLOBAL *Global + ); + +// +// Protocol APIs +// +EFI_STATUS +EFIAPI +FvbProtocolGetAttributes ( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, + OUT EFI_FVB_ATTRIBUTES_2 *Attributes + ); + +EFI_STATUS +EFIAPI +FvbProtocolSetAttributes ( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, + IN OUT EFI_FVB_ATTRIBUTES_2 *Attributes + ); + +EFI_STATUS +EFIAPI +FvbProtocolGetPhysicalAddress ( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, + OUT EFI_PHYSICAL_ADDRESS *Address + ); + +EFI_STATUS +EFIAPI +FvbProtocolGetBlockSize ( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, + IN CONST EFI_LBA Lba, + OUT UINTN *BlockSize, + OUT UINTN *NumOfBlocks + ); + +EFI_STATUS +EFIAPI +FvbProtocolRead ( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, + IN CONST EFI_LBA Lba, + IN CONST UINTN Offset, + IN OUT UINTN *NumBytes, + IN UINT8 *Buffer + ); + +EFI_STATUS +EFIAPI +FvbProtocolWrite ( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, + IN EFI_LBA Lba, + IN UINTN Offset, + IN OUT UINTN *NumBytes, + IN UINT8 *Buffer + ); + +EFI_STATUS +EFIAPI +FvbProtocolEraseBlocks ( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, + ... + ); + +// +// The following functions have different implementations dependent on the +// module type chosen for building this driver. +// +VOID +InstallProtocolInterfaces ( + IN EFI_FW_VOL_BLOCK_DEVICE *FvbDevice + ); + +VOID +InstallVirtualAddressChangeHandler ( + VOID + ); +#endif diff --git a/Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/RamFvbServicesRunt= imeDxe/FwBlockServiceDxe.c b/Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/Ra= mFvbServicesRuntimeDxe/FwBlockServiceDxe.c new file mode 100644 index 0000000..7fea42e --- /dev/null +++ b/Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/RamFvbServicesRuntimeDxe/= FwBlockServiceDxe.c @@ -0,0 +1,156 @@ +/**@file + Functions related to the Firmware Volume Block service whose + implementation is specific to the runtime DXE driver build. + + Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All right= s reserved.
+ Copyright (C) 2015, Red Hat, Inc. + Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.
+ + This program and the accompanying materials are licensed and made availa= ble + 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 IMP= LIED. +**/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "FwBlockService.h" +#include "RamFlash.h" + +VOID +InstallProtocolInterfaces ( + IN EFI_FW_VOL_BLOCK_DEVICE *FvbDevice + ) +{ + EFI_STATUS Status; + EFI_HANDLE FwbHandle; + EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *OldFwbInterface; + + // + // Find a handle with a matching device path that has supports FW Block + // protocol + // + Status =3D gBS->LocateDevicePath (&gEfiFirmwareVolumeBlockProtocolGuid, + &FvbDevice->DevicePath, &FwbHandle); + if (EFI_ERROR (Status)) { + // + // LocateDevicePath fails so install a new interface and device path + // + FwbHandle =3D NULL; + DEBUG ((EFI_D_INFO, "Installing RAM FVB\n")); + Status =3D gBS->InstallMultipleProtocolInterfaces ( + &FwbHandle, + &gEfiFirmwareVolumeBlockProtocolGuid, + &FvbDevice->FwVolBlockInstance, + &gEfiDevicePathProtocolGuid, + FvbDevice->DevicePath, + NULL + ); + ASSERT_EFI_ERROR (Status); + } else if (IsDevicePathEnd (FvbDevice->DevicePath)) { + // + // Device already exists, so reinstall the FVB protocol + // + Status =3D gBS->HandleProtocol ( + FwbHandle, + &gEfiFirmwareVolumeBlockProtocolGuid, + (VOID**)&OldFwbInterface + ); + ASSERT_EFI_ERROR (Status); + + DEBUG ((EFI_D_INFO, "Reinstalling FVB for Ram flash region\n")); + Status =3D gBS->ReinstallProtocolInterface ( + FwbHandle, + &gEfiFirmwareVolumeBlockProtocolGuid, + OldFwbInterface, + &FvbDevice->FwVolBlockInstance + ); + ASSERT_EFI_ERROR (Status); + } else { + // + // There was a FVB protocol on an End Device Path node + // + ASSERT (FALSE); + } +} + + +STATIC +VOID +EFIAPI +FvbVirtualAddressChangeEvent ( + IN EFI_EVENT Event, + IN VOID *Context + ) +/*++ + + Routine Description: + + Fixup internal data so that EFI and SAL can be call in virtual mode. + Call the passed in Child Notify event and convert the mFvbModuleGlobal + date items to there virtual address. + + Arguments: + + (Standard EFI notify event - EFI_EVENT_NOTIFY) + + Returns: + + None + +--*/ +{ + EFI_FW_VOL_INSTANCE *FwhInstance; + UINTN Index; + + FwhInstance =3D mFvbModuleGlobal->FvInstance; + EfiConvertPointer (0x0, (VOID **) &mFvbModuleGlobal->FvInstance); + + // + // Convert the base address of all the instances + // + Index =3D 0; + while (Index < mFvbModuleGlobal->NumFv) { + EfiConvertPointer (0x0, (VOID **) &FwhInstance->FvBase); + FwhInstance =3D (EFI_FW_VOL_INSTANCE *) + ( + (UINTN) ((UINT8 *) FwhInstance) + + FwhInstance->VolumeHeader.HeaderLength + + (sizeof (EFI_FW_VOL_INSTANCE) - sizeof (EFI_FIRMWARE_VOLUME_HEADER= )) + ); + Index++; + } + + EfiConvertPointer (0x0, (VOID **) &mFvbModuleGlobal); + RamFlashConvertPointers (); +} + + +VOID +InstallVirtualAddressChangeHandler ( + VOID + ) +{ + EFI_STATUS Status; + EFI_EVENT VirtualAddressChangeEvent; + + Status =3D gBS->CreateEventEx ( + EVT_NOTIFY_SIGNAL, + TPL_NOTIFY, + FvbVirtualAddressChangeEvent, + NULL, + &gEfiEventVirtualAddressChangeGuid, + &VirtualAddressChangeEvent + ); + ASSERT_EFI_ERROR (Status); +} diff --git a/Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/RamFvbServicesRunt= imeDxe/RamFlash.c b/Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/RamFvbServi= cesRuntimeDxe/RamFlash.c new file mode 100644 index 0000000..47d62c7 --- /dev/null +++ b/Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/RamFvbServicesRuntimeDxe/= RamFlash.c @@ -0,0 +1,151 @@ +/** @file + Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All right= s reserved.
+ + This program and the accompanying materials are licensed and made availa= ble + 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 IMP= LIED. + +**/ + +#include +#include +#include + +#include "RamFlash.h" + +UINT8 *mFlashBase; + +STATIC UINTN mFdBlockSize =3D 0; +STATIC UINTN mFdBlockCount =3D 0; + +STATIC +volatile UINT8* +RamFlashPtr ( + IN EFI_LBA Lba, + IN UINTN Offset + ) +{ + return mFlashBase + ((UINTN)Lba * mFdBlockSize) + Offset; +} + +/** + Read from Ram Flash + + @param[in] Lba The starting logical block index to read from. + @param[in] Offset Offset into the block at which to begin reading. + @param[in] NumBytes On input, indicates the requested read size. On + output, indicates the actual number of bytes read + @param[in] Buffer Pointer to the buffer to read into. + +**/ +EFI_STATUS +RamFlashRead ( + IN EFI_LBA Lba, + IN UINTN Offset, + IN UINTN *NumBytes, + IN UINT8 *Buffer + ) +{ + UINT8 *Ptr; + + // + // Only write to the first 64k. We don't bother saving the FTW Spare + // block into the flash memory. + // + if (Lba >=3D mFdBlockCount) { + return EFI_INVALID_PARAMETER; + } + + // + // Get flash address + // + Ptr =3D (UINT8*) RamFlashPtr (Lba, Offset); + + CopyMem (Buffer, Ptr, *NumBytes); + + return EFI_SUCCESS; +} + + +/** + Write to Ram Flash + + @param[in] Lba The starting logical block index to write to. + @param[in] Offset Offset into the block at which to begin writing. + @param[in] NumBytes On input, indicates the requested write size. On + output, indicates the actual number of bytes written + @param[in] Buffer Pointer to the data to write. + +**/ +EFI_STATUS +RamFlashWrite ( + IN EFI_LBA Lba, + IN UINTN Offset, + IN UINTN *NumBytes, + IN UINT8 *Buffer + ) +{ + volatile UINT8 *Ptr; + UINTN Loop; + + // + // Only write to the first 64k. We don't bother saving the FTW Spare + // block into the flash memory. + // + if (Lba >=3D mFdBlockCount) { + return EFI_INVALID_PARAMETER; + } + + // + // Program flash + // + Ptr =3D RamFlashPtr (Lba, Offset); + for (Loop =3D 0; Loop < *NumBytes; Loop++) { + *Ptr =3D Buffer[Loop]; + Ptr++; + } + + return EFI_SUCCESS; +} + + +/** + Erase a Ram Flash block + + @param Lba The logical block index to erase. + +**/ +EFI_STATUS +RamFlashEraseBlock ( + IN EFI_LBA Lba + ) +{ + + return EFI_SUCCESS; +} + + +/** + Initializes Ram flash memory support + + @retval EFI_WRITE_PROTECTED The Ram flash device is not present. + @retval EFI_SUCCESS The Ram flash device is supported. + +**/ +EFI_STATUS +RamFlashInitialize ( + VOID + ) +{ + mFlashBase =3D (UINT8*)(UINTN) PcdGet32 (PcdVariableFdBaseAddress); + mFdBlockSize =3D PcdGet32 (PcdVariableFdBlockSize); + ASSERT(PcdGet32 (PcdVariableFdSize) % mFdBlockSize =3D=3D 0); + mFdBlockCount =3D PcdGet32 (PcdVariableFdSize) / mFdBlockSize; + + return EFI_SUCCESS; +} + diff --git a/Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/RamFvbServicesRunt= imeDxe/RamFlash.h b/Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/RamFvbServi= cesRuntimeDxe/RamFlash.h new file mode 100644 index 0000000..4bd8cd2 --- /dev/null +++ b/Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/RamFvbServicesRuntimeDxe/= RamFlash.h @@ -0,0 +1,92 @@ +/** @file + Ram flash device for EFI variable + + Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All right= s reserved.
+ + This program and the accompanying materials are licensed and made availa= ble + 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 IMP= LIED. + +**/ + +#ifndef __RAM_FLASH_H__ +#define __RAM_FLASH_H__ + +#include + +extern UINT8 *mFlashBase; + +/** + Read from Ram Flash + + @param[in] Lba The starting logical block index to read from. + @param[in] Offset Offset into the block at which to begin reading. + @param[in] NumBytes On input, indicates the requested read size. On + output, indicates the actual number of bytes read + @param[in] Buffer Pointer to the buffer to read into. + +**/ +EFI_STATUS +RamFlashRead ( + IN EFI_LBA Lba, + IN UINTN Offset, + IN UINTN *NumBytes, + IN UINT8 *Buffer + ); + + +/** + Write to Ram Flash + + @param[in] Lba The starting logical block index to write to. + @param[in] Offset Offset into the block at which to begin writing. + @param[in] NumBytes On input, indicates the requested write size. On + output, indicates the actual number of bytes written + @param[in] Buffer Pointer to the data to write. + +**/ +EFI_STATUS +RamFlashWrite ( + IN EFI_LBA Lba, + IN UINTN Offset, + IN UINTN *NumBytes, + IN UINT8 *Buffer + ); + + +/** + Erase a Ram Flash block + + @param Lba The logical block index to erase. + +**/ +EFI_STATUS +RamFlashEraseBlock ( + IN EFI_LBA Lba + ); + + +/** + Initializes Ram flash memory support + + @retval EFI_WRITE_PROTECTED The Ram flash device is not present. + @retval EFI_SUCCESS The Ram flash device is supported. + +**/ +EFI_STATUS +RamFlashInitialize ( + VOID + ); + + +VOID +RamFlashConvertPointers ( + VOID + ); + +#endif + diff --git a/Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/RamFvbServicesRunt= imeDxe/RamFlashDxe.c b/Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/RamFvbSe= rvicesRuntimeDxe/RamFlashDxe.c new file mode 100644 index 0000000..030a96f --- /dev/null +++ b/Platform/RiscV/SiFive/U500Pkg/Universal/Dxe/RamFvbServicesRuntimeDxe/= RamFlashDxe.c @@ -0,0 +1,26 @@ +/** @file + Ram flash device for EFI variable + + Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All right= s reserved.
+ + This program and the accompanying materials are licensed and made availa= ble + 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 IMP= LIED. + +**/ + +#include + +#include "RamFlash.h" + +VOID +RamFlashConvertPointers ( + VOID + ) +{ + EfiConvertPointer (0x0, (VOID **) &mFlashBase); +} -- 2.7.4