From nobody Wed May 15 11:47:12 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+111308+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+111308+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=arm.com ARC-Seal: i=1; a=rsa-sha256; t=1700135167; cv=none; d=zohomail.com; s=zohoarc; b=HJi9zGZ15t5SVt1CUh2mN08NZa7BqevVv3HUf9civ+0QL4jCaSyEt9aBxcnztKxhAzeS6G70xU6uYsSQ7qrXd8t25WUp6/nZ12+BvNYe/t1Hk+SG3ny9JiJ+UBv6tCORuTT2/0Qy1g/0SsZOmkFlXppqMqyVdUxfkQIcUHu5Lcs= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1700135167; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:Reply-To:References:Sender:Subject:Subject:To:To:Message-Id; bh=UDchYwwqV2FsvamKjb6wz3r42kI5hhomra9p5WBh1sQ=; b=Kv0763csj8OAC1LLO1solm6uL/dsZiX94tfIr7gjwTtHT3hqXHKTj5LW2uQABkK1alHxBCujSU1cKW5fcjZqr2fUpKVv7A7Q1T0Mv9OxO7siTAG5WKeaDQYkKvyZxI6iUWeMUSD/RaFCZ3HhBarNxNoPmWMns7W+uB1j9n5i6kM= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+111308+1787277+3901457@groups.io; dmarc=fail header.from= (p=none dis=none) Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1700135167458319.467609320261; Thu, 16 Nov 2023 03:46:07 -0800 (PST) Return-Path: DKIM-Signature: a=rsa-sha256; bh=F0OtNevIYTZAGLOje/aXRsd5wSJVkbDlnwA9DPzdUYM=; c=relaxed/simple; d=groups.io; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References:MIME-Version:Precedence:List-Subscribe:List-Help:Sender:List-Id:Mailing-List:Delivered-To:Reply-To:List-Unsubscribe-Post:List-Unsubscribe:Content-Transfer-Encoding; s=20140610; t=1700135167; v=1; b=GHTaVvUbh4yWCR3/0ES8TE4RSb7InZ8NoZ4l4++S6U6rEXhwiNhdoBIoEeEhKyhZXAJvnPFo 4MBrJ0SKds9+yCKmGJe/30TsBeH1J59znIAoXpCgQE5Bisr/veyqIGweFinU2kvjzjJziKPPJka Pv1SoJvL47hBEolrOMEazgA8= X-Received: by 127.0.0.2 with SMTP id 229WYY1788612xSnhNoiSjCZ; Thu, 16 Nov 2023 03:46:07 -0800 X-Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by mx.groups.io with SMTP id smtpd.web10.4905.1700135166509550407 for ; Thu, 16 Nov 2023 03:46:06 -0800 X-Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 25F2E1595; Thu, 16 Nov 2023 03:46:52 -0800 (PST) X-Received: from usa.arm.com (a077434.blr.arm.com [10.162.17.62]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 65B633F7B4; Thu, 16 Nov 2023 03:46:04 -0800 (PST) From: "sahil" To: devel@edk2.groups.io Cc: Ard Biesheuvel , Leif Lindholm , Sami Mujawar , Sahil Subject: [edk2-devel] [edk2-platforms][PATCH V1 1/5] Silicon/ARM/NeoverseN1Soc: Enable SCP QSPI flash region Date: Thu, 16 Nov 2023 17:15:50 +0530 Message-Id: <20231116114554.4055517-2-sahil@arm.com> In-Reply-To: <20231116114554.4055517-1-sahil@arm.com> References: <20231116114554.4055517-1-sahil@arm.com> MIME-Version: 1.0 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,sahil@arm.com List-Unsubscribe-Post: List-Unsubscribe=One-Click List-Unsubscribe: X-Gm-Message-State: XAEpn64moeX60Rs17Sq5aL41x1787277AA= Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1700135168851100001 Content-Type: text/plain; charset="utf-8" Enable SCP QSPI flash region access by adding it in the PlatformLibMem Signed-off-by: sahil Reviewed-by: Thomas Abraham --- Silicon/ARM/NeoverseN1Soc/Include/NeoverseN1Soc.h | 6 +++++- Silicon/ARM/NeoverseN1Soc/Library/PlatformLib/PlatformLibMem.c | 10 ++++++= ++-- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/Silicon/ARM/NeoverseN1Soc/Include/NeoverseN1Soc.h b/Silicon/AR= M/NeoverseN1Soc/Include/NeoverseN1Soc.h index 097160c7e2d1..92b8c9c45775 100644 --- a/Silicon/ARM/NeoverseN1Soc/Include/NeoverseN1Soc.h +++ b/Silicon/ARM/NeoverseN1Soc/Include/NeoverseN1Soc.h @@ -1,6 +1,6 @@ /** @file * -* Copyright (c) 2018 - 2020, ARM Limited. All rights reserved. +* Copyright (c) 2018 - 2023, ARM Limited. All rights reserved. * * SPDX-License-Identifier: BSD-2-Clause-Patent * @@ -41,6 +41,10 @@ #define NEOVERSEN1SOC_EXP_PERIPH_BASE0 0x1C000000 #define NEOVERSEN1SOC_EXP_PERIPH_BASE0_SZ 0x1300000 =20 +// SCP QSPI flash device +#define NEOVERSEN1SOC_SCP_QSPI_AHB_BASE 0x18000000 +#define NEOVERSEN1SOC_SCP_QSPI_AHB_SZ 0x2000000 + // Base address to a structure of type NEOVERSEN1SOC_PLAT_INFO which is // pre-populated by a earlier boot stage #define NEOVERSEN1SOC_PLAT_INFO_STRUCT_BASE (NEOVERSEN1SOC_NON_SE= CURE_SRAM_BASE + \ diff --git a/Silicon/ARM/NeoverseN1Soc/Library/PlatformLib/PlatformLibMem.c= b/Silicon/ARM/NeoverseN1Soc/Library/PlatformLib/PlatformLibMem.c index 9e8a1efc557d..eb099953fe29 100644 --- a/Silicon/ARM/NeoverseN1Soc/Library/PlatformLib/PlatformLibMem.c +++ b/Silicon/ARM/NeoverseN1Soc/Library/PlatformLib/PlatformLibMem.c @@ -1,6 +1,6 @@ /** @file =20 - Copyright (c) 2018 - 2021, ARM Limited. All rights reserved.
+ Copyright (c) 2018 - 2023, ARM Limited. All rights reserved.
=20 SPDX-License-Identifier: BSD-2-Clause-Patent =20 @@ -13,7 +13,7 @@ #include =20 // The total number of descriptors, including the final "end-of-table" des= criptor. -#define MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS 19 +#define MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS 20 =20 /** Returns the Virtual Memory Map of the platform. @@ -184,6 +184,12 @@ ArmPlatformGetVirtualMemoryMap ( VirtualMemoryTable[Index].Length =3D NEOVERSEN1SOC_EXP_PERIPH_B= ASE0_SZ; VirtualMemoryTable[Index].Attributes =3D ARM_MEMORY_REGION_ATTRIBUT= E_DEVICE; =20 + // SCP QSPI flash device + VirtualMemoryTable[++Index].PhysicalBase =3D NEOVERSEN1SOC_SCP_QSPI_AHB= _BASE; + VirtualMemoryTable[Index].VirtualBase =3D NEOVERSEN1SOC_SCP_QSPI_AHB= _BASE; + VirtualMemoryTable[Index].Length =3D NEOVERSEN1SOC_SCP_QSPI_AHB= _SZ; + VirtualMemoryTable[Index].Attributes =3D ARM_MEMORY_REGION_ATTRIBUT= E_DEVICE; + if (PlatInfo->MultichipMode =3D=3D 1) { //Remote DDR (2GB) VirtualMemoryTable[++Index].PhysicalBase =3D PcdGet64 (PcdExtMemorySp= ace) + --=20 2.25.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 (#111308): https://edk2.groups.io/g/devel/message/111308 Mute This Topic: https://groups.io/mt/102625033/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- From nobody Wed May 15 11:47:12 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+111309+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+111309+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=arm.com ARC-Seal: i=1; a=rsa-sha256; t=1700135170; cv=none; d=zohomail.com; s=zohoarc; b=VDcAsrk6MPwHDMfzzmxAzgkvgd9KNf/FtPUN1M4w0Wqf/f+NmZiZ4HOMU117bGZwZmlMjVGF31grwCQpzxao98BPtOLTLDnVyha8BIfmY9f2+JAAZ6aT13zxfVLEwLHt7qv7A7CyIXcLEAE81ccZuGbEh9vGbVR3uQZ3ZrqykSw= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1700135170; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:Reply-To:References:Sender:Subject:Subject:To:To:Message-Id; bh=2yaXbcJ+pgLYm2ART4KzxoNwPaLCJMFII07jjJEi3N4=; b=MDDrydb4eWHuU2CXEKgWw65d9MVdRu0QfClsXZC7k2CqMAQa6W5KYhIv0aOoW6t2uvJIWWUPKr1jAzFQ6kEEKAJ0HN7N9rNXY0Cc3rCMmrKj6wdCizxjst7XJwGMG2f8yPiLYLHKysA7JIHHfTpeoTEAdcJUJw3wWg4kSbo/2gM= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+111309+1787277+3901457@groups.io; dmarc=fail header.from= (p=none dis=none) Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1700135169993709.5947305990973; Thu, 16 Nov 2023 03:46:09 -0800 (PST) Return-Path: DKIM-Signature: a=rsa-sha256; bh=nYMoAd2qCA1TeVSPO8k5YBCkJDitivIF0YmaLkM+CdQ=; c=relaxed/simple; d=groups.io; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References:MIME-Version:Precedence:List-Subscribe:List-Help:Sender:List-Id:Mailing-List:Delivered-To:Reply-To:List-Unsubscribe-Post:List-Unsubscribe:Content-Transfer-Encoding; s=20140610; t=1700135169; v=1; b=SDivnF59fZrlgefPzQlDrylj8xycyEsaxrQKGLHxOBfC17tZe/EN6I/3vkaXIepGOedMMOLG sLrwN6oYUbdvuwrK6UHUBbozBjT5YzalWXTxjKnze1D8o5xDRnIfN/ZAomU8OuU4ykVEqQ0h+U6 ojfDpp/dDNIKEbYAXGekSXWk= X-Received: by 127.0.0.2 with SMTP id SnXHYY1788612xbhDc5GLMRL; Thu, 16 Nov 2023 03:46:09 -0800 X-Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by mx.groups.io with SMTP id smtpd.web11.4937.1700135168738047255 for ; Thu, 16 Nov 2023 03:46:09 -0800 X-Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 4B2841650; Thu, 16 Nov 2023 03:46:54 -0800 (PST) X-Received: from usa.arm.com (a077434.blr.arm.com [10.162.17.62]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 8BF803F7B4; Thu, 16 Nov 2023 03:46:06 -0800 (PST) From: "sahil" To: devel@edk2.groups.io Cc: Ard Biesheuvel , Leif Lindholm , Sami Mujawar , Sahil Subject: [edk2-devel] [edk2-platforms][PATCH V1 2/5] Silicon/ARM/NeoverseN1Soc: NOR flash library for N1Sdp Date: Thu, 16 Nov 2023 17:15:51 +0530 Message-Id: <20231116114554.4055517-3-sahil@arm.com> In-Reply-To: <20231116114554.4055517-1-sahil@arm.com> References: <20231116114554.4055517-1-sahil@arm.com> MIME-Version: 1.0 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,sahil@arm.com List-Unsubscribe-Post: List-Unsubscribe=One-Click List-Unsubscribe: X-Gm-Message-State: kDa0NcuJdJIFDOiOptNvdu4Vx1787277AA= Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1700135170576100005 Content-Type: text/plain; charset="utf-8" Add NOR flash library, this library provides APIs for getting the list of NOR flash devices on the platform. Signed-off-by: sahil Reviewed-by: Sami Mujawar --- Silicon/ARM/NeoverseN1Soc/Library/NorFlashLib/NorFlashLib.inf | 36 +++++++= +++++++ Silicon/ARM/NeoverseN1Soc/Library/NorFlashLib/NorFlashLib.c | 52 +++++++= +++++++++++++ 2 files changed, 88 insertions(+) diff --git a/Silicon/ARM/NeoverseN1Soc/Library/NorFlashLib/NorFlashLib.inf = b/Silicon/ARM/NeoverseN1Soc/Library/NorFlashLib/NorFlashLib.inf new file mode 100644 index 000000000000..14f81125c4e1 --- /dev/null +++ b/Silicon/ARM/NeoverseN1Soc/Library/NorFlashLib/NorFlashLib.inf @@ -0,0 +1,36 @@ +## @file +# NOR flash lib for ARM Neoverse N1 platform. +# +# Copyright (c) 2023, ARM Limited. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION =3D 0x0001001B + BASE_NAME =3D NorFlashNeoverseN1SocLib + FILE_GUID =3D 7006fcf1-a585-4272-92e3-b286b1dff5bb + MODULE_TYPE =3D DXE_DRIVER + VERSION_STRING =3D 1.0 + LIBRARY_CLASS =3D NorFlashPlatformLib + +[Sources.common] + NorFlashLib.c + +[Packages] + MdeModulePkg/MdeModulePkg.dec + MdePkg/MdePkg.dec + Platform/ARM/ARM.dec + Silicon/ARM/NeoverseN1Soc/NeoverseN1Soc.dec + +[LibraryClasses] + BaseLib + DebugLib + IoLib + +[FixedPcd] + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize diff --git a/Silicon/ARM/NeoverseN1Soc/Library/NorFlashLib/NorFlashLib.c b/= Silicon/ARM/NeoverseN1Soc/Library/NorFlashLib/NorFlashLib.c new file mode 100644 index 000000000000..a508d7d77373 --- /dev/null +++ b/Silicon/ARM/NeoverseN1Soc/Library/NorFlashLib/NorFlashLib.c @@ -0,0 +1,52 @@ +/** @file +* NOR flash lib for ARM Neoverse N1 platform +* +* Copyright (c) 2023, ARM Limited. All rights reserved.
+* +* SPDX-License-Identifier: BSD-2-Clause-Patent +* +**/ + +#include +#include +#include +#include +#include + +#define FW_ENV_REGION_BASE FixedPcdGet32 (PcdFlashNvStorageVariableBase) +#define FW_ENV_REGION_SIZE (FixedPcdGet32 (PcdFlashNvStorageVariableSize)= + \ + FixedPcdGet32 (PcdFlashNvStorageFtwW= orkingSize) + \ + FixedPcdGet32 (PcdFlashNvStorageFtwS= pareSize)) + +STATIC NOR_FLASH_DESCRIPTION mNorFlashDevices[] =3D { + { + /// Environment variable region + NEOVERSEN1SOC_SCP_QSPI_AHB_BASE, ///< device base + FW_ENV_REGION_BASE, ///< region base + FW_ENV_REGION_SIZE, ///< region size + SIZE_4KB, ///< block size + }, +}; + +/** + Get NOR flash region info + + @param[out] NorFlashDevices NOR flash regions info. + @param[out] Count number of flash instance. + + @retval EFI_SUCCESS Success. +**/ +EFI_STATUS +NorFlashPlatformGetDevices ( + OUT NOR_FLASH_DESCRIPTION **NorFlashDevices, + OUT UINT32 *Count + ) +{ + if ((NorFlashDevices =3D=3D NULL) || (Count =3D=3D NULL)) { + return EFI_INVALID_PARAMETER; + } + + *NorFlashDevices =3D mNorFlashDevices; + *Count =3D ARRAY_SIZE (mNorFlashDevices); + return EFI_SUCCESS; +} --=20 2.25.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 (#111309): https://edk2.groups.io/g/devel/message/111309 Mute This Topic: https://groups.io/mt/102625034/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- From nobody Wed May 15 11:47:12 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+111311+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+111311+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=arm.com ARC-Seal: i=1; a=rsa-sha256; t=1700135172; cv=none; d=zohomail.com; s=zohoarc; b=bq4XP3o43LsnwG9mG2Yscv9o0GPxev7FtdqZZJTSmCtvwzDaYOA9xpx4bLFDzOBVoVYb2+kfmoAzg8PvBqYNdpYB9VISaQ8o8CtVoJ/XnWbxisdGsGCsEe+W/ZL208nMWAB2vnQH/C6Pqy5I8J1Y01FynNE9U5kqxaBulrZXo3Q= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1700135172; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:Reply-To:References:Sender:Subject:Subject:To:To:Message-Id; bh=aKXW4xQ6OU8pKfzXkIpXZLJPqV4t3sHBy+VSJTlwa30=; b=RfsSgM92gtOlO07t7N65B2RnStLiqFjS8zz4lOoICBRAxXDSXK9OD8oj8nmHmJS18QDJMsFQQuZaLMXByoSnBfxC1mJg7zCd+D+Nfrnv3nBKDaVwQvIkAc5gDc/2AmYHXhU1fdX2Vi10dEdpLV+gGPyumtaOGcOHKZemBcofrfA= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+111311+1787277+3901457@groups.io; dmarc=fail header.from= (p=none dis=none) Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1700135172554204.1552897488948; Thu, 16 Nov 2023 03:46:12 -0800 (PST) Return-Path: DKIM-Signature: a=rsa-sha256; bh=QonLO/Nv84XLFobWDXSlt+G+++JC9Fa2oL66jx8TMmU=; c=relaxed/simple; d=groups.io; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References:MIME-Version:Precedence:List-Subscribe:List-Help:Sender:List-Id:Mailing-List:Delivered-To:Reply-To:List-Unsubscribe-Post:List-Unsubscribe:Content-Transfer-Encoding; s=20140610; t=1700135172; v=1; b=rXMm1tSwuqubT+Za4/4sgzdCpILuMcAewzGE8VYlQYIYU54ljwxawAxKbvVB0PcmGrZSk5IG iJpGy5XqBwJvr/cRuSChlUw6hNp2E2/SFYWLctM4gCgic1X/qN34abKF5ofQ7VBPZ+gVloTXBqd LSAfYuMStIN/K8EB3Ve0eVws= X-Received: by 127.0.0.2 with SMTP id Oq8LYY1788612xyCvs0pQdh8; Thu, 16 Nov 2023 03:46:12 -0800 X-Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by mx.groups.io with SMTP id smtpd.web11.4942.1700135171466269171 for ; Thu, 16 Nov 2023 03:46:11 -0800 X-Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 2D63F1688; Thu, 16 Nov 2023 03:46:57 -0800 (PST) X-Received: from usa.arm.com (a077434.blr.arm.com [10.162.17.62]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id B2E983F7B4; Thu, 16 Nov 2023 03:46:08 -0800 (PST) From: "sahil" To: devel@edk2.groups.io Cc: Ard Biesheuvel , Leif Lindholm , Sami Mujawar , Sahil Subject: [edk2-devel] [edk2-platforms][PATCH V1 3/5] Platform/ARM/N1Sdp: NOR flash Dxe Driver for N1Sdp Date: Thu, 16 Nov 2023 17:15:52 +0530 Message-Id: <20231116114554.4055517-4-sahil@arm.com> In-Reply-To: <20231116114554.4055517-1-sahil@arm.com> References: <20231116114554.4055517-1-sahil@arm.com> MIME-Version: 1.0 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,sahil@arm.com List-Unsubscribe-Post: List-Unsubscribe=One-Click List-Unsubscribe: X-Gm-Message-State: 5etKhakEMh7alEdMQVyqzGhvx1787277AA= Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1700135174686100015 Content-Type: text/plain; charset="utf-8" Add NOR flash DXE driver, this brings up NV storage on QSPI's flash device using FVB protocol. Signed-off-by: sahil Reviewed-by: Thomas Abraham --- Platform/ARM/N1Sdp/N1SdpPlatform.dec | 5 +- Platform/ARM/N1Sdp/Drivers/CadenceQspiDxe/CadenceQspiDxe.inf | 72 ++ Platform/ARM/N1Sdp/Drivers/CadenceQspiDxe/CadenceQspiReg.h | 33 + Platform/ARM/N1Sdp/Drivers/CadenceQspiDxe/NorFlash.h | 491 ++++++= +++ Platform/ARM/N1Sdp/Drivers/CadenceQspiDxe/CadenceQspiDxe.c | 409 ++++++= ++ Platform/ARM/N1Sdp/Drivers/CadenceQspiDxe/NorFlash.c | 1100 ++++++= ++++++++++++++ Platform/ARM/N1Sdp/Drivers/CadenceQspiDxe/NorFlashFvb.c | 647 ++++++= ++++++ 7 files changed, 2756 insertions(+), 1 deletion(-) diff --git a/Platform/ARM/N1Sdp/N1SdpPlatform.dec b/Platform/ARM/N1Sdp/N1Sd= pPlatform.dec index 16937197b8e8..67b5f4c871b6 100644 --- a/Platform/ARM/N1Sdp/N1SdpPlatform.dec +++ b/Platform/ARM/N1Sdp/N1SdpPlatform.dec @@ -1,7 +1,7 @@ ## @file # Describes the N1Sdp configuration. # -# Copyright (c) 2021, ARM Limited. All rights reserved.
+# Copyright (c) 2021-2023, ARM Limited. All rights reserved.
# # SPDX-License-Identifier: BSD-2-Clause-Patent ## @@ -89,3 +89,6 @@ # unmapped reserved region results in a DECERR response. # gArmN1SdpTokenSpaceGuid.PcdCsComponentSize|0x1000|UINT32|0x00000049 + + # Base address of Cadence QSPI controller configuration registers + gArmN1SdpTokenSpaceGuid.PcdCadenceQspiDxeRegBaseAddress|0x1C0C0000|UINT3= 2|0x0000004A diff --git a/Platform/ARM/N1Sdp/Drivers/CadenceQspiDxe/CadenceQspiDxe.inf b= /Platform/ARM/N1Sdp/Drivers/CadenceQspiDxe/CadenceQspiDxe.inf new file mode 100644 index 000000000000..62a4944c95db --- /dev/null +++ b/Platform/ARM/N1Sdp/Drivers/CadenceQspiDxe/CadenceQspiDxe.inf @@ -0,0 +1,72 @@ +## @file +# NOR flash DXE +# +# Copyright (c) 2023, ARM Limited. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION =3D 0x0001001B + BASE_NAME =3D CadenceQspiDxe + FILE_GUID =3D CC8A9713-4442-4A6C-B389-8B46490A0641 + MODULE_TYPE =3D DXE_RUNTIME_DRIVER + VERSION_STRING =3D 0.1 + ENTRY_POINT =3D NorFlashInitialise + +[Sources] + CadenceQspiDxe.c + CadenceQspiReg.h + NorFlash.c + NorFlash.h + NorFlashFvb.c + +[Packages] + EmbeddedPkg/EmbeddedPkg.dec + MdeModulePkg/MdeModulePkg.dec + MdePkg/MdePkg.dec + Platform/ARM/ARM.dec + Platform/ARM/N1Sdp/N1SdpPlatform.dec + +[LibraryClasses] + BaseLib + BaseMemoryLib + DebugLib + DevicePathLib + DxeServicesTableLib + HobLib + IoLib + MemoryAllocationLib + NorFlashInfoLib + NorFlashPlatformLib + TimerLib + UefiBootServicesTableLib + UefiDriverEntryPoint + UefiLib + UefiRuntimeLib + UefiRuntimeServicesTableLib + +[Guids] + gEdkiiNvVarStoreFormattedGuid + gEfiAuthenticatedVariableGuid + gEfiEventVirtualAddressChangeGuid + gEfiSystemNvDataFvGuid + gEfiVariableGuid + gEfiGlobalVariableGuid + +[Protocols] + gEfiDevicePathProtocolGuid + gEfiFirmwareVolumeBlockProtocolGuid + +[FixedPcd] + gArmN1SdpTokenSpaceGuid.PcdCadenceQspiDxeRegBaseAddress + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize + +[Depex] + gEfiCpuArchProtocolGuid diff --git a/Platform/ARM/N1Sdp/Drivers/CadenceQspiDxe/CadenceQspiReg.h b/P= latform/ARM/N1Sdp/Drivers/CadenceQspiDxe/CadenceQspiReg.h new file mode 100644 index 000000000000..535e6d738d31 --- /dev/null +++ b/Platform/ARM/N1Sdp/Drivers/CadenceQspiDxe/CadenceQspiReg.h @@ -0,0 +1,33 @@ +/** @file + + Copyright (c) 2023, ARM Limited. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef CADENCE_QSPI_REG_H_ +#define CADENCE_QSPI_REG_H_ + +// QSPI Controller defines +#define CDNS_QSPI_FLASH_CMD_CTRL_REG_OFFSET 0x90 +#define CDNS_QSPI_FLASH_CMD_CTRL_REG_EXECUTE 0x01 +#define CDNS_QSPI_FLASH_CMD_CTRL_REG_ADDR_ENABLE 0x01 +#define CDNS_QSPI_FLASH_CMD_CTRL_REG_ADDR_BIT_POS 19 +#define CDNS_QSPI_FLASH_CMD_CTRL_REG_ADDR_BYTE_BIT_POS 16 +#define CDNS_QSPI_FLASH_CMD_CTRL_REG_STATUS_BIT 0x02 +#define CDNS_QSPI_FLASH_CMD_CTRL_REG_OPCODE_BIT_POS 24 +#define CDNS_QSPI_FLASH_CMD_CTRL_REG_READ_ENABLE 0x01 +#define CDNS_QSPI_FLASH_CMD_CTRL_REG_READ_BYTE_3B 0x02 +#define CDNS_QSPI_FLASH_CMD_CTRL_REG_READEN_BIT_POS 23 +#define CDNS_QSPI_FLASH_CMD_CTRL_REG_READBYTE_BIT_POS 20 +#define CDNS_QSPI_FLASH_CMD_CTRL_REG_DUMMY_8C 0x8 +#define CDNS_QSPI_FLASH_CMD_CTRL_REG_DUMMY_BIT_POS 7 +#define CDNS_QSPI_FLASH_CMD_CTRL_REG_NUM_DATA_BYTES(x) ((x - 1) << CDNS_Q= SPI_FLASH_CMD_CTRL_REG_READBYTE_BIT_POS) +#define CDNS_QSPI_FLASH_CMD_CTRL_REG_NUM_ADDR_BYTES(x) ((x - 1) << CDNS_Q= SPI_FLASH_CMD_CTRL_REG_ADDR_BYTE_BIT_POS) + +#define CDNS_QSPI_FLASH_CMD_READ_DATA_REG_OFFSET 0xA0 + +#define CDNS_QSPI_FLASH_CMD_ADDR_REG_OFFSET 0x94 + +#endif /* CADENCE_QSPI_REG_H_ */ diff --git a/Platform/ARM/N1Sdp/Drivers/CadenceQspiDxe/NorFlash.h b/Platfor= m/ARM/N1Sdp/Drivers/CadenceQspiDxe/NorFlash.h new file mode 100644 index 000000000000..38ae1c2fae89 --- /dev/null +++ b/Platform/ARM/N1Sdp/Drivers/CadenceQspiDxe/NorFlash.h @@ -0,0 +1,491 @@ +/** @file + + Copyright (c) 2023, ARM Limited. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef NOR_FLASH_DXE_H_ +#define NOR_FLASH_DXE_H_ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "CadenceQspiReg.h" + +#define NOR_FLASH_ERASE_RETRY 10 + +#define GET_NOR_BLOCK_ADDRESS(BaseAddr, Lba, LbaSize) \ + ((BaseAddr) + (UINTN)((Lba) * (LbaSi= ze))) + +#define NOR_FLASH_SIGNATURE SIGNATURE_32('S', 'n', 'o', 'r') +#define INSTANCE_FROM_FVB_THIS(a) CR(a, NOR_FLASH_INSTANCE, FvbProtocol, = \ + NOR_FLASH_SIGNATURE) + +#define NOR_FLASH_POLL_FSR BIT0 + +typedef struct _NOR_FLASH_INSTANCE NOR_FLASH_INSTANCE; + +typedef EFI_STATUS (*NOR_FLASH_INITIALIZE) ( + NOR_FLASH_INSTANCE *Instance + ); + +#pragma pack(1) +typedef struct { + VENDOR_DEVICE_PATH Vendor; + UINT8 Index; + EFI_DEVICE_PATH_PROTOCOL End; +} NOR_FLASH_DEVICE_PATH; +#pragma pack() + +struct _NOR_FLASH_INSTANCE { + UINT32 Signature; + EFI_HANDLE Handle; + + BOOLEAN Initialized; + NOR_FLASH_INITIALIZE Initialize; + + UINTN HostRegisterBaseAddress; + UINTN DeviceBaseAddress; + UINTN RegionBaseAddress; + UINTN Size; + UINTN BlockSize; + UINTN LastBlock; + EFI_LBA StartLba; + EFI_LBA OffsetLba; + + EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL FvbProtocol; + VOID *ShadowBuffer; + + NOR_FLASH_DEVICE_PATH DevicePath; + + UINT32 Flags; +}; + +typedef struct { + EFI_TPL OriginalTPL; + BOOLEAN InterruptsEnabled; +} NOR_FLASH_LOCK_CONTEXT; + +/** + Lock all pending read/write to Nor flash device + + @param[in] Context Nor flash device context structure. +**/ +VOID +EFIAPI +NorFlashLock ( + IN NOR_FLASH_LOCK_CONTEXT *Context + ); + +/** + Unlock all pending read/write to Nor flash device + + @param[in] Context Nor flash device context structure. +**/ +VOID +EFIAPI +NorFlashUnlock ( + IN NOR_FLASH_LOCK_CONTEXT *Context + ); + +extern UINTN mFlashNvStorageVariableBase; + +/** + Create Nor flash Instance for given region. + + @param[in] HostRegisterBase Base address of Nor flash controller. + @param[in] NorFlashDeviceBase Base address of flash device. + @param[in] NorFlashRegionBase Base address of flash region on devi= ce. + @param[in] NorFlashSize Size of flash region. + @param[in] Index Index of given flash region. + @param[in] BlockSize Block size of NOR flash device. + @param[in] HasVarStore Boolean set for VarStore on given re= gion. + @param[out] NorFlashInstance Instance of given flash region. + + @retval EFI_SUCCESS On successful creation of NOR flash = instance. +**/ +EFI_STATUS +NorFlashCreateInstance ( + IN UINTN HostRegisterBase, + IN UINTN NorFlashDeviceBase, + IN UINTN NorFlashRegionBase, + IN UINTN NorFlashSize, + IN UINT32 Index, + IN UINT32 BlockSize, + IN BOOLEAN HasVarStore, + OUT NOR_FLASH_INSTANCE **NorFlashInstance + ); + +/** + Install Fv block on to variable store region + + @param[in] Instance Instance of Nor flash variable region. + + @retval EFI_SUCCESS The entry point is executed successfully. +**/ +EFI_STATUS +EFIAPI +NorFlashFvbInitialize ( + IN NOR_FLASH_INSTANCE *Instance + ); + +/** + Check the integrity of firmware volume header. + + @param[in] Instance Instance of Nor flash variable region. + + @retval EFI_SUCCESS The firmware volume is consistent. + @retval EFI_NOT_FOUND The firmware volume has been corrupted. + +**/ +EFI_STATUS +ValidateFvHeader ( + IN NOR_FLASH_INSTANCE *Instance + ); + +/** + Initialize the FV Header and Variable Store Header + to support variable operations. + + @param[in] Instance Location to Initialize the headers + + @retval EFI_SUCCESS Fv init is done + +**/ +EFI_STATUS +InitializeFvAndVariableStoreHeaders ( + IN NOR_FLASH_INSTANCE *Instance + ); + +/** + Retrieves the attributes and current settings of the block. + + @param[in] This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOC= OL instance. + + @param[out] Attributes Pointer to EFI_FVB_ATTRIBUTES_2 in which the at= tributes and + current settings are returned. + Type EFI_FVB_ATTRIBUTES_2 is defined in + EFI_FIRMWARE_VOLUME_HEADER. + + @retval EFI_SUCCESS The firmware volume attributes were returned. + +**/ +EFI_STATUS +EFIAPI +FvbGetAttributes ( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, + OUT EFI_FVB_ATTRIBUTES_2 *Attributes + ); + +/** + Sets configurable firmware volume attributes and returns the + new settings of the firmware volume. + + + @param[in] This EFI_FIRMWARE_VOLUME_BLOCK2_PR= OTOCOL instance. + + @param[in, out] Attributes On input, Attributes is a poi= nter to + EFI_FVB_ATTRIBUTES_2 that con= tains the desired + firmware volume settings. + On successful return, it cont= ains the new + settings of the firmware volu= me. + + @retval EFI_UNSUPPORTED The firmware volume attribute= s are not supported. + +**/ +EFI_STATUS +EFIAPI +FvbSetAttributes ( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, + IN OUT EFI_FVB_ATTRIBUTES_2 *Attributes + ); + +/** + Retrieves the base address of a memory-mapped firmware volume. + This function should be called only for memory-mapped firmware volumes. + + @param[in] This EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL ins= tance. + + @param[out] Address Pointer to a caller-allocated + EFI_PHYSICAL_ADDRESS that, on successful + return from GetPhysicalAddress(), conta= ins the + base address of the firmware volume. + + @retval EFI_SUCCESS The firmware volume base address was re= turned. + +**/ +EFI_STATUS +EFIAPI +FvbGetPhysicalAddress ( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, + OUT EFI_PHYSICAL_ADDRESS *Address + ); + +/** + Retrieves the size of the requested block. + It also returns the number of additional blocks with the identical size. + The GetBlockSize() function is used to retrieve the block map + (see EFI_FIRMWARE_VOLUME_HEADER). + + + @param[in] This EFI_FIRMWARE_VOLUME_BLOCK2_PROTOC= OL instance. + + @param[in] Lba Indicates the block whose size to= return + + @param[out] BlockSize Pointer to a caller-allocated UIN= TN in which + the size of the block is returned. + + @param[out] NumberOfBlocks Pointer to a caller-allocated UIN= TN in + which the number of consecutive b= locks, + starting with Lba, is returned. A= ll + blocks in this range have a size = of + BlockSize. + + @retval EFI_SUCCESS The firmware volume base address = was returned. + + @retval EFI_INVALID_PARAMETER The requested LBA is out of range. + +**/ +EFI_STATUS +EFIAPI +FvbGetBlockSize ( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, + IN EFI_LBA Lba, + OUT UINTN *BlockSize, + OUT UINTN *NumberOfBlocks + ); + +/** + Reads the specified number of bytes into a buffer from the specified bloc= k. + + The Read() function reads the requested number of bytes from the + requested block and stores them in the provided buffer. + + @param[in] This EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL= instance. + + @param[in] Lba The starting logical block index fr= om which to read + + @param[in] Offset Offset into the block at which to b= egin reading. + + @param[in, out] NumBytes Pointer to a UINTN. + At entry, *NumBytes contains the to= tal size of the + buffer. *NumBytes should have a non= zero value. + At exit, *NumBytes contains the tot= al number of + bytes read. + + @param[in out] Buffer Pointer to a caller-allocated buffe= r that will be + used to hold the data that is read. + + @retval EFI_SUCCESS The firmware volume was read succes= sfully, and + contents are in Buffer. + + @retval EFI_BAD_BUFFER_SIZE Read attempted across an LBA bounda= ry. + + @retval EFI_DEVICE_ERROR The block device is not functioning= correctly and + could not be read. + +**/ +EFI_STATUS +EFIAPI +FvbRead ( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, + IN EFI_LBA Lba, + IN UINTN Offset, + IN OUT UINTN *NumBytes, + IN OUT UINT8 *Buffer + ); + +/** + Writes the specified number of bytes from the input buffer to the block. + + @param[in] This EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCO= L instance. + + @param[in] Lba The starting logical block index t= o write to. + + @param[in] Offset Offset into the block at which to = begin writing. + + @param[in, out] NumBytes The pointer to a UINTN. + At entry, *NumBytes contains the t= otal size of the + buffer. + At exit, *NumBytes contains the to= tal number of + bytes actually written. + + @param[in] Buffer The pointer to a caller-allocated = buffer that + contains the source for the write. + + @retval EFI_SUCCESS The firmware volume was written su= ccessfully. + +**/ +EFI_STATUS +EFIAPI +FvbWrite ( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, + IN EFI_LBA Lba, + IN UINTN Offset, + IN OUT UINTN *NumBytes, + IN UINT8 *Buffer + ); + +/** + Erases and initialises a firmware volume block. + + @param[in] This EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL + + @param[in] ... The variable argument list is a lis= t of tuples. + Each tuple describes a range of LBA= s to erase + and consists of the following: + - An EFI_LBA that indicates the sta= rting LBA + - A UINTN that indicates the number= of blocks + to erase. + + The list is terminated with an + EFI_LBA_LIST_TERMINATOR. + + @retval EFI_SUCCESS The erase request successfully comp= leted. + + @retval EFI_ACCESS_DENIED The firmware volume is in the Write= Disabled + state. + + @retval EFI_DEVICE_ERROR The block device is not functioning= correctly + and could not be written. + The firmware device may have been p= artially + erased. + + @retval EFI_INVALID_PARAMETER One or more of the LBAs listed in t= he variable + argument list do not exist in the f= irmware + volume. + +**/ +EFI_STATUS +EFIAPI +FvbEraseBlocks ( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, + ... + ); + +/** + This function unlock and erase an entire NOR Flash block. + + @param[in] Instance NOR flash Instance of variable store regio= n. + @param[in] BlockAddress Block address within the variable store re= gion. + + @retval EFI_SUCCESS The erase and unlock successfully complete= d. +**/ +EFI_STATUS +NorFlashUnlockAndEraseSingleBlock ( + IN NOR_FLASH_INSTANCE *Instance, + IN UINTN BlockAddress + ); + +/** + Write a full or portion of a block. + + @param[in] Instance NOR flash Instance of variable store regi= on. + @param[in] Lba The starting logical block index to write= to. + @param[in] Offset Offset into the block at which to begin w= riting. + @param[in,out] NumBytes The total size of the buffer. + @param[in] Buffer The pointer to a caller-allocated buffer = that + contains the source for the write. + + @retval EFI_SUCCESS The write is completed. +**/ +EFI_STATUS +NorFlashWriteSingleBlock ( + IN NOR_FLASH_INSTANCE *Instance, + IN EFI_LBA Lba, + IN UINTN Offset, + IN OUT UINTN *NumBytes, + IN UINT8 *Buffer + ); + +/** + Write a full block. + + @param[in] Instance NOR flash Instance of variable store = region. + @param[in] Lba The starting logical block index to w= rite to. + @param[in] BufferSizeInBytes The number of bytes to write. + @param[in] Buffer The pointer to a caller-allocated buf= fer that + contains the source for the write. + + @retval EFI_SUCCESS The write is completed. +**/ +EFI_STATUS +NorFlashWriteBlocks ( + IN NOR_FLASH_INSTANCE *Instance, + IN EFI_LBA Lba, + IN UINTN BufferSizeInBytes, + IN VOID *Buffer + ); + +/** + Read a full block. + + @param[in] Instance NOR flash Instance of variable store r= egion. + @param[in] Lba The starting logical block index to re= ad from. + @param[in] BufferSizeInBytes The number of bytes to read. + @param[out] Buffer The pointer to a caller-allocated buff= er that + should be copied with read data. + + @retval EFI_SUCCESS The read is completed. +**/ +EFI_STATUS +NorFlashReadBlocks ( + IN NOR_FLASH_INSTANCE *Instance, + IN EFI_LBA Lba, + IN UINTN BufferSizeInBytes, + OUT VOID *Buffer + ); + +/** + Read from nor flash. + + @param[in] Instance NOR flash Instance of variable store r= egion. + @param[in] Lba The starting logical block index to re= ad from. + @param[in] Offset Offset into the block at which to begi= n reading. + @param[in] BufferSizeInBytes The number of bytes to read. + @param[out] Buffer The pointer to a caller-allocated buff= er that + should copied with read data. + + @retval EFI_SUCCESS The read is completed. +**/ +EFI_STATUS +NorFlashRead ( + IN NOR_FLASH_INSTANCE *Instance, + IN EFI_LBA Lba, + IN UINTN Offset, + IN UINTN BufferSizeInBytes, + OUT VOID *Buffer + ); + +/** + Read JEDEC ID of NOR flash device. + + @param[in] Instance NOR flash Instance of variable store region. + @param[out] JedecId JEDEC ID of NOR flash device. + + @retval EFI_SUCCESS The write is completed. +**/ +EFI_STATUS +NorFlashReadID ( + IN NOR_FLASH_INSTANCE *Instance, + OUT UINT8 JedecId[3] + ); + +#define SPINOR_SR_WIP BIT0 // Write in progress + +#define SPINOR_OP_WREN 0x06 // Write enable +#define SPINOR_OP_BE_4K 0x20 // Erase 4KiB block +#define SPINOR_OP_RDID 0x9f // Read JEDEC ID +#define SPINOR_OP_RDSR 0x05 // Read status register + +#define SPINOR_SR_WIP_POLL_TIMEOUT_MS 1000u // Status Register read timeo= ut + +#endif /* NOR_FLASH_DXE_H_ */ diff --git a/Platform/ARM/N1Sdp/Drivers/CadenceQspiDxe/CadenceQspiDxe.c b/P= latform/ARM/N1Sdp/Drivers/CadenceQspiDxe/CadenceQspiDxe.c new file mode 100644 index 000000000000..fffe689161a6 --- /dev/null +++ b/Platform/ARM/N1Sdp/Drivers/CadenceQspiDxe/CadenceQspiDxe.c @@ -0,0 +1,409 @@ +/** @file + NOR flash DXE + + Copyright (c) 2023, ARM Limited. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "NorFlash.h" + +STATIC NOR_FLASH_INSTANCE **mNorFlashInstances; +STATIC UINT32 mNorFlashDeviceCount; + +STATIC EFI_EVENT mNorFlashVirtualAddrChangeEvent; + +/** + Install Fv block onto variable store region + + @param[in] Instance Instance of Nor flash variable region. + + @retval EFI_SUCCESS The entry point is executed successfully. +**/ +EFI_STATUS +EFIAPI +NorFlashFvbInitialize ( + IN NOR_FLASH_INSTANCE *Instance + ) +{ + EFI_STATUS Status; + UINT32 FvbNumLba; + EFI_BOOT_MODE BootMode; + UINTN RuntimeMmioRegionSize; + UINTN RuntimeMmioDeviceSize; + UINTN BlockSize; + + DEBUG ((DEBUG_INFO, "NorFlashFvbInitialize\n")); + + BlockSize =3D Instance->BlockSize; + + // FirmwareVolumeHeader->FvLength is declared to have the Variable area + // AND the FTW working area AND the FTW Spare contiguous. + ASSERT ( + PcdGet32 (PcdFlashNvStorageVariableBase) + + PcdGet32 (PcdFlashNvStorageVariableSize) =3D=3D + PcdGet32 (PcdFlashNvStorageFtwWorkingBase) + ); + ASSERT ( + PcdGet32 (PcdFlashNvStorageFtwWorkingBase) + + PcdGet32 (PcdFlashNvStorageFtwWorkingSize) =3D=3D + PcdGet32 (PcdFlashNvStorageFtwSpareBase) + ); + + // Check if the size of the area is at least one block size. + ASSERT ( + (PcdGet32 (PcdFlashNvStorageVariableSize) > 0) && + (PcdGet32 (PcdFlashNvStorageVariableSize) / BlockSize > 0) + ); + ASSERT ( + (PcdGet32 (PcdFlashNvStorageFtwWorkingSize) > 0) && + (PcdGet32 (PcdFlashNvStorageFtwWorkingSize) / BlockSize > 0) + ); + ASSERT ( + (PcdGet32 (PcdFlashNvStorageFtwSpareSize) > 0) && + (PcdGet32 (PcdFlashNvStorageFtwSpareSize) / BlockSize > 0) + ); + + // Ensure the Variable areas are aligned on block size boundaries. + ASSERT ((PcdGet32 (PcdFlashNvStorageVariableBase) % BlockSize) =3D=3D 0); + ASSERT ((PcdGet32 (PcdFlashNvStorageFtwWorkingBase) % BlockSize) =3D=3D = 0); + ASSERT ((PcdGet32 (PcdFlashNvStorageFtwSpareBase) % BlockSize) =3D=3D 0); + + Instance->Initialized =3D TRUE; + mFlashNvStorageVariableBase =3D FixedPcdGet32 (PcdFlashNvStorageVariable= Base); + + // Set the index of the first LBA for the FVB. + Instance->StartLba =3D (PcdGet32 (PcdFlashNvStorageVariableBase) - + Instance->RegionBaseAddress) / BlockSize; + + BootMode =3D GetBootModeHob (); + if (BootMode =3D=3D BOOT_WITH_DEFAULT_SETTINGS) { + Status =3D EFI_INVALID_PARAMETER; + } else { + // Determine if there is a valid header at the beginning of the NorFla= sh. + Status =3D ValidateFvHeader (Instance); + } + + // Install the Default FVB header if required. + if (EFI_ERROR (Status)) { + // There is no valid header, so time to install one. + DEBUG ((DEBUG_INFO, "%a: The FVB Header is not valid.\n", __func__)); + DEBUG (( + DEBUG_INFO, + "%a: Installing a correct one for this volume.\n", + __func__ + )); + + // Erase all the NorFlash that is reserved for variable storage. + FvbNumLba =3D (PcdGet32 (PcdFlashNvStorageVariableSize) + + PcdGet32 (PcdFlashNvStorageFtwWorkingSize) + + PcdGet32 (PcdFlashNvStorageFtwSpareSize)) / + Instance->BlockSize; + + Status =3D FvbEraseBlocks ( + &Instance->FvbProtocol, + (EFI_LBA)0, + FvbNumLba, + EFI_LBA_LIST_TERMINATOR + ); + if (EFI_ERROR (Status)) { + return Status; + } + + // Install all appropriate headers. + Status =3D InitializeFvAndVariableStoreHeaders (Instance); + if (EFI_ERROR (Status)) { + return Status; + } + + // validate FV header again if FV was created successfully. + Status =3D ValidateFvHeader (Instance); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "ValidateFvHeader is failed \n")); + return Status; + } + } + + // The driver implementing the variable read service can now be dispatch= ed; + // the varstore headers are in place. + Status =3D gBS->InstallProtocolInterface ( + &gImageHandle, + &gEdkiiNvVarStoreFormattedGuid, + EFI_NATIVE_INTERFACE, + NULL + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "%a: Failed to install gEdkiiNvVarStoreFormattedGuid\n", + __func__ + )); + return Status; + } + + // Declare the Non-Volatile storage as EFI_MEMORY_RUNTIME. + RuntimeMmioRegionSize =3D Instance->Size; + RuntimeMmioDeviceSize =3D Instance->RegionBaseAddress - Instance->Device= BaseAddress; + + Status =3D gDS->AddMemorySpace ( + EfiGcdMemoryTypeMemoryMappedIo, + Instance->RegionBaseAddress, + RuntimeMmioRegionSize, + EFI_MEMORY_UC | EFI_MEMORY_RUNTIME + ); + ASSERT_EFI_ERROR (Status); + + Status =3D gDS->AddMemorySpace ( + EfiGcdMemoryTypeMemoryMappedIo, + Instance->DeviceBaseAddress, + RuntimeMmioDeviceSize, + EFI_MEMORY_UC | EFI_MEMORY_RUNTIME + ); + ASSERT_EFI_ERROR (Status); + + Status =3D gDS->SetMemorySpaceAttributes ( + Instance->RegionBaseAddress, + RuntimeMmioRegionSize, + EFI_MEMORY_UC | EFI_MEMORY_RUNTIME + ); + ASSERT_EFI_ERROR (Status); + + Status =3D gDS->SetMemorySpaceAttributes ( + Instance->DeviceBaseAddress, + RuntimeMmioDeviceSize, + EFI_MEMORY_UC | EFI_MEMORY_RUNTIME + ); + ASSERT_EFI_ERROR (Status); + + return Status; +} + +/** + Fixup internal data so that EFI can be called in virtual mode. + convert any pointers in lib to virtual mode. + + @param[in] Event The Event that is being processed + @param[in] Context Event Context +**/ +STATIC +VOID +EFIAPI +NorFlashVirtualNotifyEvent ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + UINTN Index; + + EfiConvertPointer (0x0, (VOID **)&mFlashNvStorageVariableBase); + + for (Index =3D 0; Index < mNorFlashDeviceCount; Index++) { + EfiConvertPointer ( + 0x0, + (VOID **)&mNorFlashInstances[Index]->HostRegisterBaseAddress + ); + EfiConvertPointer ( + 0x0, + (VOID **)&mNorFlashInstances[Index]->DeviceBaseAddress + ); + EfiConvertPointer ( + 0x0, + (VOID **)&mNorFlashInstances[Index]->RegionBaseAddress + ); + + // Convert Fvb. + EfiConvertPointer ( + 0x0, + (VOID **)&mNorFlashInstances[Index]->FvbProtocol.EraseBlocks + ); + EfiConvertPointer ( + 0x0, + (VOID **)&mNorFlashInstances[Index]->FvbProtocol.GetAttributes + ); + EfiConvertPointer ( + 0x0, + (VOID **)&mNorFlashInstances[Index]->FvbProtocol.GetBlockSize + ); + EfiConvertPointer ( + 0x0, + (VOID **)&mNorFlashInstances[Index]->FvbProtocol.GetPhysicalAddress + ); + EfiConvertPointer ( + 0x0, + (VOID **)&mNorFlashInstances[Index]->FvbProtocol.Read + ); + EfiConvertPointer ( + 0x0, + (VOID **)&mNorFlashInstances[Index]->FvbProtocol.SetAttributes + ); + EfiConvertPointer ( + 0x0, + (VOID **)&mNorFlashInstances[Index]->FvbProtocol.Write + ); + + if (mNorFlashInstances[Index]->ShadowBuffer !=3D NULL) { + EfiConvertPointer (0x0, (VOID **)&mNorFlashInstances[Index]->ShadowB= uffer); + } + } +} + +/** + Entrypoint of Platform Nor flash DXE driver + + @param[in] ImageHandle The firmware allocated handle for the EFI = image. + @param[in] SystemTable A pointer to the EFI System Table. + + @retval EFI_SUCCESS The entry point is executed successfully. +**/ +EFI_STATUS +EFIAPI +NorFlashInitialise ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + EFI_PHYSICAL_ADDRESS HostRegisterBaseAddress; + UINT32 Index; + NOR_FLASH_DESCRIPTION *NorFlashDevices; + BOOLEAN ContainVariableStorage; + + HostRegisterBaseAddress =3D PcdGet32 (PcdCadenceQspiDxeRegBaseAddress); + + Status =3D gDS->AddMemorySpace ( + EfiGcdMemoryTypeMemoryMappedIo, + HostRegisterBaseAddress, + SIZE_64KB, + EFI_MEMORY_UC | EFI_MEMORY_RUNTIME + ); + ASSERT_EFI_ERROR (Status); + + Status =3D gDS->SetMemorySpaceAttributes ( + HostRegisterBaseAddress, + SIZE_64KB, + EFI_MEMORY_UC | EFI_MEMORY_RUNTIME + ); + ASSERT_EFI_ERROR (Status); + + // Initialize NOR flash instances. + Status =3D NorFlashPlatformGetDevices (&NorFlashDevices, &mNorFlashDevic= eCount); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "NorFlashInitialise: Fail to get Nor Flash device= s\n")); + return Status; + } + + mNorFlashInstances =3D AllocateRuntimePool ( + sizeof (NOR_FLASH_INSTANCE *) * + mNorFlashDeviceCount + ); + + if (mNorFlashInstances =3D=3D NULL) { + DEBUG (( + DEBUG_ERROR, + "NorFlashInitialise: Failed to allocate mem for NorFlashInstance\n" + )); + return EFI_OUT_OF_RESOURCES; + } + + for (Index =3D 0; Index < mNorFlashDeviceCount; Index++) { + // Check if this NOR Flash device contain the variable storage region. + ContainVariableStorage =3D + (NorFlashDevices[Index].RegionBaseAddress <=3D + PcdGet32 (PcdFlashNvStorageVariableBase)) && + (PcdGet32 (PcdFlashNvStorageVariableBase) + + PcdGet32 (PcdFlashNvStorageVariableSize) <=3D + NorFlashDevices[Index].RegionBaseAddress + NorFlashDevices[Index].S= ize); + + Status =3D NorFlashCreateInstance ( + HostRegisterBaseAddress, + NorFlashDevices[Index].DeviceBaseAddress, + NorFlashDevices[Index].RegionBaseAddress, + NorFlashDevices[Index].Size, + Index, + NorFlashDevices[Index].BlockSize, + ContainVariableStorage, + &mNorFlashInstances[Index] + ); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "NorFlashInitialise: Fail to create instance for NorFlash[%d]\n", + Index + )); + continue; + } + + Status =3D gBS->InstallMultipleProtocolInterfaces ( + &mNorFlashInstances[Index]->Handle, + &gEfiDevicePathProtocolGuid, + &mNorFlashInstances[Index]->DevicePath, + &gEfiFirmwareVolumeBlockProtocolGuid, + &mNorFlashInstances[Index]->FvbProtocol, + NULL + ); + ASSERT_EFI_ERROR (Status); + } + + // Register for the virtual address change event. + Status =3D gBS->CreateEventEx ( + EVT_NOTIFY_SIGNAL, + TPL_NOTIFY, + NorFlashVirtualNotifyEvent, + NULL, + &gEfiEventVirtualAddressChangeGuid, + &mNorFlashVirtualAddrChangeEvent + ); + ASSERT_EFI_ERROR (Status); + + return Status; +} + +/** + Lock all pending read/write to Nor flash device + + @param[in] Context Nor flash device context structure. +**/ +VOID +EFIAPI +NorFlashLock ( + IN NOR_FLASH_LOCK_CONTEXT *Context + ) +{ + if (!EfiAtRuntime ()) { + // Raise TPL to TPL_HIGH to stop anyone from interrupting us. + Context->OriginalTPL =3D gBS->RaiseTPL (TPL_HIGH_LEVEL); + } else { + Context->InterruptsEnabled =3D SaveAndDisableInterrupts (); + } +} + +/** + Unlock all pending read/write to Nor flash device + + @param[in] Context Nor flash device context structure. +**/ +VOID +EFIAPI +NorFlashUnlock ( + IN NOR_FLASH_LOCK_CONTEXT *Context + ) +{ + if (!EfiAtRuntime ()) { + // Interruptions can resume. + gBS->RestoreTPL (Context->OriginalTPL); + } else if (Context->InterruptsEnabled) { + SetInterruptState (TRUE); + } +} diff --git a/Platform/ARM/N1Sdp/Drivers/CadenceQspiDxe/NorFlash.c b/Platfor= m/ARM/N1Sdp/Drivers/CadenceQspiDxe/NorFlash.c new file mode 100644 index 000000000000..be7b626c5697 --- /dev/null +++ b/Platform/ARM/N1Sdp/Drivers/CadenceQspiDxe/NorFlash.c @@ -0,0 +1,1100 @@ +/** @file + + Copyright (c) 2023 ARM Limited. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include +#include +#include +#include +#include + +#include "NorFlash.h" + +STATIC CONST NOR_FLASH_INSTANCE mNorFlashInstanceTemplate =3D { + NOR_FLASH_SIGNATURE, // Signature + NULL, // Handle + + FALSE, // Initialized + NULL, // Initialize + + 0, // HostRegisterBaseAddress + 0, // DeviceBaseAddress + 0, // RegionBaseAddress + 0, // Size + 0, // BlockSize + 0, // LastBlock + 0, // StartLba + 0, // OffsetLba + + { + FvbGetAttributes, // GetAttributes + FvbSetAttributes, // SetAttributes + FvbGetPhysicalAddress, // GetPhysicalAddress + FvbGetBlockSize, // GetBlockSize + FvbRead, // Read + FvbWrite, // Write + FvbEraseBlocks, // EraseBlocks + NULL, // ParentHandle + }, // FvbProtoccol; + NULL, // ShadowBuffer + + { + { + { + HARDWARE_DEVICE_PATH, + HW_VENDOR_DP, + { + (UINT8)(OFFSET_OF (NOR_FLASH_DEVICE_PATH, End)), + (UINT8)(OFFSET_OF (NOR_FLASH_DEVICE_PATH, End) >> 8) + } + }, + { 0x0, 0x0, 0x0, { 0x0, 0x0, 0x0, 0x0,= 0x0, 0x0, 0x0, 0x0 } + }, + }, + 0, // Index + + { + END_DEVICE_PATH_TYPE, + END_ENTIRE_DEVICE_PATH_SUBTYPE, + { sizeof (EFI_DEVICE_PATH_PROTOCOL), 0 } + } + }, // DevicePath + 0 // Flags +}; + +/** + Execute Flash cmd ctrl and Read Status. + + @param[in] Instance NOR flash Instance. + @param[in] Val Value to be written to Flash cmd ctrl R= egister. + + @retval EFI_SUCCESS Request is executed successfully. + +**/ +STATIC +EFI_STATUS +CdnsQspiExecuteCommand ( + IN NOR_FLASH_INSTANCE *Instance, + IN UINT32 Val + ) +{ + // Set the command + MmioWrite32 ( + Instance->HostRegisterBaseAddress + CDNS_QSPI_FLASH_CMD_CTRL_REG_OFFSE= T, + Val + ); + // Execute the command + MmioWrite32 ( + Instance->HostRegisterBaseAddress + CDNS_QSPI_FLASH_CMD_CTRL_REG_OFFSE= T, + Val | CDNS_QSPI_FLASH_CMD_CTRL_REG_EXECUTE + ); + + // Wait until command has been executed + while ((MmioRead32 (Instance->HostRegisterBaseAddress + CDNS_QSPI_FLASH_= CMD_CTRL_REG_OFFSET) + & CDNS_QSPI_FLASH_CMD_CTRL_REG_STATUS_BIT) =3D=3D CDNS_QSPI_FLAS= H_CMD_CTRL_REG_STATUS_BIT) + { + continue; + } + + return EFI_SUCCESS; +} + +/** + Create Nor flash Instance for given region. + + @param[in] HostRegisterBase Base address of Nor flash controller. + @param[in] NorFlashDeviceBase Base address of flash device. + @param[in] NorFlashRegionBase Base address of flash region on devi= ce. + @param[in] NorFlashSize Size of flash region. + @param[in] Index Index of given flash region. + @param[in] BlockSize Block size of NOR flash device. + @param[in] HasVarStore Boolean set for VarStore on given re= gion. + @param[out] NorFlashInstance Instance of given flash region. + + @retval EFI_SUCCESS On successful creation of NOR flash = instance. +**/ +EFI_STATUS +NorFlashCreateInstance ( + IN UINTN HostRegisterBase, + IN UINTN NorFlashDeviceBase, + IN UINTN NorFlashRegionBase, + IN UINTN NorFlashSize, + IN UINT32 Index, + IN UINT32 BlockSize, + IN BOOLEAN HasVarStore, + OUT NOR_FLASH_INSTANCE **NorFlashInstance + ) +{ + EFI_STATUS Status; + NOR_FLASH_INSTANCE *Instance; + NOR_FLASH_INFO *FlashInfo; + UINT8 JedecId[3]; + + ASSERT (NorFlashInstance !=3D NULL); + Instance =3D AllocateRuntimeCopyPool ( + sizeof (mNorFlashInstanceTemplate), + &mNorFlashInstanceTemplate + ); + if (Instance =3D=3D NULL) { + return EFI_OUT_OF_RESOURCES; + } + + Instance->HostRegisterBaseAddress =3D HostRegisterBase; + Instance->DeviceBaseAddress =3D NorFlashDeviceBase; + Instance->RegionBaseAddress =3D NorFlashRegionBase; + Instance->Size =3D NorFlashSize; + Instance->BlockSize =3D BlockSize; + Instance->LastBlock =3D (NorFlashSize / BlockSize) - 1; + + Instance->OffsetLba =3D (NorFlashRegionBase - NorFlashDeviceBase) / Bloc= kSize; + + CopyGuid (&Instance->DevicePath.Vendor.Guid, &gEfiCallerIdGuid); + Instance->DevicePath.Index =3D (UINT8)Index; + + Status =3D NorFlashReadID (Instance, JedecId); + if (EFI_ERROR (Status)) { + goto FreeInstance; + } + + Status =3D NorFlashGetInfo (JedecId, &FlashInfo, TRUE); + if (EFI_ERROR (Status)) { + goto FreeInstance; + } + + NorFlashPrintInfo (FlashInfo); + + Instance->Flags =3D 0; + if (FlashInfo->Flags & NOR_FLASH_WRITE_FSR) { + Instance->Flags =3D NOR_FLASH_POLL_FSR; + } + + Instance->ShadowBuffer =3D AllocateRuntimePool (BlockSize); + if (Instance->ShadowBuffer =3D=3D NULL) { + Status =3D EFI_OUT_OF_RESOURCES; + goto FreeInstance; + } + + if (HasVarStore) { + Instance->Initialize =3D NorFlashFvbInitialize; + } + + *NorFlashInstance =3D Instance; + FreePool (FlashInfo); + return EFI_SUCCESS; + +FreeInstance: + FreePool (Instance); + return Status; +} + +/** + Converts milliseconds into number of ticks of the performance counter. + + @param[in] Milliseconds Milliseconds to convert into ticks. + + @retval Milliseconds expressed as number of ticks. + +**/ +STATIC +UINT64 +MilliSecondsToTicks ( + IN UINTN Milliseconds + ) +{ + CONST UINT64 NanoSecondsPerTick =3D GetTimeInNanoSecond (1); + + return (Milliseconds * 1000000) / NanoSecondsPerTick; +} + +/** + Poll Status register for NOR flash erase/write completion. + + @param[in] Instance NOR flash Instance. + + @retval EFI_SUCCESS Request is executed successfully. + @retval EFI_TIMEOUT Operation timed out. + @retval EFI_DEVICE_ERROR Controller operartion failed. + +**/ +STATIC +EFI_STATUS +NorFlashPollStatusRegister ( + IN NOR_FLASH_INSTANCE *Instance + ) +{ + BOOLEAN SRegDone; + UINT32 val; + + val =3D SPINOR_OP_RDSR << CDNS_QSPI_FLASH_CMD_CTRL_REG_OPCODE_BIT_POS | + CDNS_QSPI_FLASH_CMD_CTRL_REG_READ_ENABLE << CDNS_QSPI_FLASH_CMD_CT= RL_REG_READEN_BIT_POS | + CDNS_QSPI_FLASH_CMD_CTRL_REG_NUM_DATA_BYTES (1) | + CDNS_QSPI_FLASH_CMD_CTRL_REG_DUMMY_8C << CDNS_QSPI_FLASH_CMD_CTRL_= REG_DUMMY_BIT_POS; + + CONST UINT64 TickOut =3D + GetPerformanceCounter () + MilliSecondsToTicks (SPINOR_SR_WIP_POLL_TIM= EOUT_MS); + + do { + if (GetPerformanceCounter () > TickOut) { + DEBUG (( + DEBUG_ERROR, + "NorFlashPollStatusRegister: Timeout waiting for erase/write.\n" + )); + return EFI_TIMEOUT; + } + + if (EFI_ERROR (CdnsQspiExecuteCommand (Instance, val))) { + return EFI_DEVICE_ERROR; + } + + SRegDone =3D + (MmioRead8 (Instance->HostRegisterBaseAddress + CDNS_QSPI_FLASH_CMD_= READ_DATA_REG_OFFSET) + & SPINOR_SR_WIP) =3D=3D 0; + } while (!SRegDone); + + return EFI_SUCCESS; +} + +/** + Check whether NOR flash opertions are Locked. + + @param[in] Instance NOR flash Instance. + @param[in] BlockAddress BlockAddress in NOR flash device. + + @retval FALSE If NOR flash is not locked. +**/ +STATIC +BOOLEAN +NorFlashBlockIsLocked ( + IN NOR_FLASH_INSTANCE *Instance, + IN UINTN BlockAddress + ) +{ + return FALSE; +} + +/** + Unlock NOR flash operations on given block. + + @param[in] Instance NOR flash instance. + @param[in] BlockAddress BlockAddress in NOR flash device. + + @retval EFI_SUCCESS NOR flash operations is unlocked. +**/ +STATIC +EFI_STATUS +NorFlashUnlockSingleBlock ( + IN NOR_FLASH_INSTANCE *Instance, + IN UINTN BlockAddress + ) +{ + return EFI_SUCCESS; +} + +/** + Unlock NOR flash operations if it is necessary. + + @param[in] Instance NOR flash instance. + @param[in] BlockAddress BlockAddress in NOR flash device. + + @retval EFI_SUCCESS Request is executed successfully. +**/ +STATIC +EFI_STATUS +NorFlashUnlockSingleBlockIfNecessary ( + IN NOR_FLASH_INSTANCE *Instance, + IN UINTN BlockAddress + ) +{ + EFI_STATUS Status; + + Status =3D EFI_SUCCESS; + + if (!NorFlashBlockIsLocked (Instance, BlockAddress)) { + Status =3D NorFlashUnlockSingleBlock (Instance, BlockAddress); + } + + return Status; +} + +/** + Enable write to NOR flash device. + + @param[in] Instance NOR flash instance. + + @retval EFI_SUCCESS Request is executed successfully. +**/ +STATIC +EFI_STATUS +NorFlashEnableWrite ( + IN NOR_FLASH_INSTANCE *Instance + ) +{ + UINT32 val; + + DEBUG ((DEBUG_INFO, "NorFlashEnableWrite()\n")); + val =3D (SPINOR_OP_WREN << CDNS_QSPI_FLASH_CMD_CTRL_REG_OPCODE_BIT_POS); + if (EFI_ERROR (CdnsQspiExecuteCommand (Instance, val))) { + return EFI_DEVICE_ERROR; + } + + return EFI_SUCCESS; +} + +/** + The following function presumes that the block has already been unlocked. + + @param[in] Instance NOR flash instance. + @param[in] BlockAddress Block address within the variable regio= n. + + @retval EFI_SUCCESS Request is executed successfully. + **/ +EFI_STATUS +NorFlashEraseSingleBlock ( + IN NOR_FLASH_INSTANCE *Instance, + IN UINTN BlockAddress + ) +{ + UINT32 DevConfigVal; + UINT32 EraseOffset; + + EraseOffset =3D 0x0; + + DEBUG (( + DEBUG_INFO, + "NorFlashEraseSingleBlock(BlockAddress=3D0x%08x)\n", + BlockAddress + )); + + if (EFI_ERROR (NorFlashEnableWrite (Instance))) { + return EFI_DEVICE_ERROR; + } + + EraseOffset =3D BlockAddress - Instance->DeviceBaseAddress; + + MmioWrite32 ( + Instance->HostRegisterBaseAddress + CDNS_QSPI_FLASH_CMD_ADDR_REG_OFFSE= T, + EraseOffset + ); + + DevConfigVal =3D SPINOR_OP_BE_4K << CDNS_QSPI_FLASH_CMD_CTRL_REG_OPCODE_= BIT_POS | + CDNS_QSPI_FLASH_CMD_CTRL_REG_ADDR_ENABLE << CDNS_QSPI_FLA= SH_CMD_CTRL_REG_ADDR_BIT_POS | + CDNS_QSPI_FLASH_CMD_CTRL_REG_NUM_ADDR_BYTES (3); + + if (EFI_ERROR (CdnsQspiExecuteCommand (Instance, DevConfigVal))) { + return EFI_DEVICE_ERROR; + } + + if (EFI_ERROR (NorFlashPollStatusRegister (Instance))) { + return EFI_DEVICE_ERROR; + } + + return EFI_SUCCESS; +} + +/** + This function unlock and erase an entire NOR Flash block. + + @param[in] Instance NOR flash Instance of variable store regio= n. + @param[in] BlockAddress Block address within the variable store re= gion. + + @retval EFI_SUCCESS The erase and unlock successfully complete= d. +**/ +EFI_STATUS +NorFlashUnlockAndEraseSingleBlock ( + IN NOR_FLASH_INSTANCE *Instance, + IN UINTN BlockAddress + ) +{ + EFI_STATUS Status; + UINTN Index; + NOR_FLASH_LOCK_CONTEXT Lock; + + NorFlashLock (&Lock); + + Index =3D 0; + do { + // Unlock the block if we have to + Status =3D NorFlashUnlockSingleBlockIfNecessary (Instance, BlockAddres= s); + if (EFI_ERROR (Status)) { + break; + } + + Status =3D NorFlashEraseSingleBlock (Instance, BlockAddress); + if (EFI_ERROR (Status)) { + break; + } + + Index++; + } while ((Index < NOR_FLASH_ERASE_RETRY) && (Status =3D=3D EFI_WRITE_PRO= TECTED)); + + if (Index =3D=3D NOR_FLASH_ERASE_RETRY) { + DEBUG (( + DEBUG_ERROR, + "EraseSingleBlock(BlockAddress=3D0x%08x: Block Locked Error (try to = erase %d times)\n", + BlockAddress, + Index + )); + } + + NorFlashUnlock (&Lock); + + return Status; +} + +/** + Write a single word to given location. + + @param[in] Instance NOR flash Instance of variable store region. + @param[in] WordAddress The address in NOR flash to write given word. + @param[in] WriteData The data to write into NOR flash location. + + @retval EFI_SUCCESS The write is completed. +**/ +STATIC +EFI_STATUS +NorFlashWriteSingleWord ( + IN NOR_FLASH_INSTANCE *Instance, + IN UINTN WordAddress, + IN UINT32 WriteData + ) +{ + DEBUG (( + DEBUG_INFO, + "NorFlashWriteSingleWord(WordAddress=3D0x%08x, WriteData=3D0x%08x)\n", + WordAddress, + WriteData + )); + + if (EFI_ERROR (NorFlashEnableWrite (Instance))) { + return EFI_DEVICE_ERROR; + } + + MmioWrite32 (WordAddress, WriteData); + if (EFI_ERROR (NorFlashPollStatusRegister (Instance))) { + return EFI_DEVICE_ERROR; + } + + return EFI_SUCCESS; +} + +/** + Write a full block to given location. + + @param[in] Instance NOR flash Instance of variable store re= gion. + @param[in] Lba The logical block address in NOR flash. + @param[in] DataBuffer The data to write into NOR flash locati= on. + @param[in] BlockSizeInWords The number of bytes to write. + + @retval EFI_SUCCESS The write is completed. +**/ +STATIC +EFI_STATUS +NorFlashWriteFullBlock ( + IN NOR_FLASH_INSTANCE *Instance, + IN EFI_LBA Lba, + IN UINT32 *DataBuffer, + IN UINT32 BlockSizeInWords + ) +{ + EFI_STATUS Status; + UINTN WordAddress; + UINT32 WordIndex; + UINTN BlockAddress; + NOR_FLASH_LOCK_CONTEXT Lock; + + Status =3D EFI_SUCCESS; + + // Get the physical address of the block + BlockAddress =3D GET_NOR_BLOCK_ADDRESS ( + Instance->RegionBaseAddress, + Lba, + BlockSizeInWords * 4 + ); + + // Start writing from the first address at the start of the block + WordAddress =3D BlockAddress; + + NorFlashLock (&Lock); + + Status =3D NorFlashUnlockAndEraseSingleBlock (Instance, BlockAddress); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "WriteSingleBlock: ERROR - Failed to Unlock and Erase the single blo= ck at 0x%X\n", + BlockAddress + )); + goto EXIT; + } + + for (WordIndex =3D 0; + WordIndex < BlockSizeInWords; + WordIndex++, DataBuffer++, WordAddress +=3D 4) + { + Status =3D NorFlashWriteSingleWord (Instance, WordAddress, *DataBuffer= ); + if (EFI_ERROR (Status)) { + goto EXIT; + } + } + +EXIT: + NorFlashUnlock (&Lock); + + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_ERROR, + "NOR FLASH Programming [WriteSingleBlock] failed at address 0x%08x. = Exit Status =3D %r.\n", + WordAddress, + Status + )); + } + + return Status; +} + +/** + Write a full block. + + @param[in] Instance NOR flash Instance of variable store re= gion. + @param[in] Lba The starting logical block index. + @param[in] BufferSizeInBytes The number of bytes to read. + @param[in] Buffer The pointer to a caller-allocated buffe= r that + contains the source for the write. + + @retval EFI_SUCCESS The write is completed. +**/ +EFI_STATUS +NorFlashWriteBlocks ( + IN NOR_FLASH_INSTANCE *Instance, + IN EFI_LBA Lba, + IN UINTN BufferSizeInBytes, + IN VOID *Buffer + ) +{ + UINT32 *pWriteBuffer; + EFI_STATUS Status; + EFI_LBA CurrentBlock; + UINT32 BlockSizeInWords; + UINT32 NumBlocks; + UINT32 BlockCount; + + Status =3D EFI_SUCCESS; + // The buffer must be valid + if (Buffer =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + // We must have some bytes to read + DEBUG (( + DEBUG_INFO, + "NorFlashWriteBlocks: BufferSizeInBytes=3D0x%x\n", + BufferSizeInBytes + )); + if (BufferSizeInBytes =3D=3D 0) { + return EFI_BAD_BUFFER_SIZE; + } + + // The size of the buffer must be a multiple of the block size + DEBUG (( + DEBUG_INFO, + "NorFlashWriteBlocks: BlockSize in bytes =3D0x%x\n", + Instance->BlockSize + )); + if ((BufferSizeInBytes % Instance->BlockSize) !=3D 0) { + return EFI_BAD_BUFFER_SIZE; + } + + // All blocks must be within the device + NumBlocks =3D ((UINT32)BufferSizeInBytes) / Instance->BlockSize; + + DEBUG (( + DEBUG_INFO, + "NorFlashWriteBlocks: NumBlocks=3D%d, LastBlock=3D%ld, Lba=3D%ld.\n", + NumBlocks, + Instance->LastBlock, + Lba + )); + + if ((Lba + NumBlocks) > (Instance->LastBlock + 1)) { + DEBUG (( + DEBUG_ERROR, + "NorFlashWriteBlocks: ERROR - Write will exceed last block.\n" + )); + return EFI_INVALID_PARAMETER; + } + + ASSERT (((UINTN)Buffer % sizeof (UINT32)) =3D=3D 0); + + BlockSizeInWords =3D Instance->BlockSize / 4; + + // Because the target *Buffer is a pointer to VOID, we must put + // all the data into a pointer to a proper data type, so use *ReadBuffer + pWriteBuffer =3D (UINT32 *)Buffer; + + CurrentBlock =3D Lba; + for (BlockCount =3D 0; + BlockCount < NumBlocks; + BlockCount++, CurrentBlock++, pWriteBuffer +=3D BlockSizeInWords) + { + DEBUG (( + DEBUG_INFO, + "NorFlashWriteBlocks: Writing block #%d\n", + (UINTN)CurrentBlock + )); + + Status =3D NorFlashWriteFullBlock ( + Instance, + CurrentBlock, + pWriteBuffer, + BlockSizeInWords + ); + + if (EFI_ERROR (Status)) { + break; + } + } + + DEBUG ((DEBUG_INFO, "NorFlashWriteBlocks: Exit Status =3D %r.\n", Status= )); + return Status; +} + +/** + Read a full block. + + @param[in] Instance NOR flash Instance of variable store r= egion. + @param[in] Lba The starting logical block index to re= ad from. + @param[in] BufferSizeInBytes The number of bytes to read. + @param[out] Buffer The pointer to a caller-allocated buff= er that + should be copied with read data. + + @retval EFI_SUCCESS The read is completed. +**/ +EFI_STATUS +NorFlashReadBlocks ( + IN NOR_FLASH_INSTANCE *Instance, + IN EFI_LBA Lba, + IN UINTN BufferSizeInBytes, + OUT VOID *Buffer + ) +{ + UINT32 NumBlocks; + UINTN StartAddress; + + DEBUG (( + DEBUG_INFO, + "NorFlashReadBlocks: BufferSize=3D0x%xB BlockSize=3D0x%xB LastBlock=3D= %ld, Lba=3D%ld.\n", + BufferSizeInBytes, + Instance->BlockSize, + Instance->LastBlock, + Lba + )); + + // The buffer must be valid + if (Buffer =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + // Return if we do not have any byte to read + if (BufferSizeInBytes =3D=3D 0) { + return EFI_SUCCESS; + } + + // The size of the buffer must be a multiple of the block size + if ((BufferSizeInBytes % Instance->BlockSize) !=3D 0) { + return EFI_BAD_BUFFER_SIZE; + } + + NumBlocks =3D ((UINT32)BufferSizeInBytes) / Instance->BlockSize; + + if ((Lba + NumBlocks) > (Instance->LastBlock + 1)) { + DEBUG (( + DEBUG_ERROR, + "NorFlashReadBlocks: ERROR - Read will exceed last block\n" + )); + return EFI_INVALID_PARAMETER; + } + + // Get the address to start reading from + StartAddress =3D GET_NOR_BLOCK_ADDRESS ( + Instance->RegionBaseAddress, + Lba, + Instance->BlockSize + ); + + // Readout the data + CopyMem (Buffer, (UINTN *)StartAddress, BufferSizeInBytes); + + return EFI_SUCCESS; +} + +/** + Read from nor flash. + + @param[in] Instance NOR flash Instance of variable store r= egion. + @param[in] Lba The starting logical block index to re= ad from. + @param[in] Offset Offset into the block at which to begi= n reading. + @param[in] BufferSizeInBytes The number of bytes to read. + @param[out] Buffer The pointer to a caller-allocated buff= er that + should copied with read data. + + @retval EFI_SUCCESS The read is completed. +**/ +EFI_STATUS +NorFlashRead ( + IN NOR_FLASH_INSTANCE *Instance, + IN EFI_LBA Lba, + IN UINTN Offset, + IN UINTN BufferSizeInBytes, + OUT VOID *Buffer + ) +{ + UINTN StartAddress; + + // The buffer must be valid + if (Buffer =3D=3D NULL) { + return EFI_INVALID_PARAMETER; + } + + // Return if we do not have any byte to read + if (BufferSizeInBytes =3D=3D 0) { + return EFI_SUCCESS; + } + + if (((Lba * Instance->BlockSize) + Offset + BufferSizeInBytes) > + Instance->Size) + { + DEBUG (( + DEBUG_ERROR, + "NorFlashRead: ERROR - Read will exceed device size.\n" + )); + return EFI_INVALID_PARAMETER; + } + + // Get the address to start reading from + StartAddress =3D GET_NOR_BLOCK_ADDRESS ( + Instance->RegionBaseAddress, + Lba, + Instance->BlockSize + ); + + // Readout the data + CopyMem (Buffer, (UINTN *)(StartAddress + Offset), BufferSizeInBytes); + + return EFI_SUCCESS; +} + +/** + Write a full or portion of a block. + + @param[in] Instance NOR flash Instance of variable store reg= ion. + @param[in] Lba The starting logical block index to writ= e to. + @param[in] Offset Offset into the block at which to begin = writing. + @param[in, out] NumBytes The total size of the buffer. + @param[in] Buffer The pointer to a caller-allocated buffer= that + contains the source for the write. + + @retval EFI_SUCCESS The write is completed. +**/ +EFI_STATUS +NorFlashWriteSingleBlock ( + IN NOR_FLASH_INSTANCE *Instance, + IN EFI_LBA Lba, + IN UINTN Offset, + IN OUT UINTN *NumBytes, + IN UINT8 *Buffer + ) +{ + EFI_STATUS Status; + UINT32 Tmp; + UINT32 TmpBuf; + UINT32 WordToWrite; + UINT32 Mask; + BOOLEAN DoErase; + UINTN BytesToWrite; + UINTN CurOffset; + UINTN WordAddr; + UINTN BlockSize; + UINTN BlockAddress; + UINTN PrevBlockAddress; + + if (Buffer =3D=3D NULL) { + DEBUG (( + DEBUG_ERROR, + "NorFlashWriteSingleBlock: ERROR - Buffer is invalid\n" + )); + return EFI_OUT_OF_RESOURCES; + } + + PrevBlockAddress =3D 0; + if (!Instance->Initialized && Instance->Initialize) { + Instance->Initialize (Instance); + } + + DEBUG (( + DEBUG_INFO, + "NorFlashWriteSingleBlock(Parameters: Lba=3D%ld, Offset=3D0x%x, *NumBy= tes=3D0x%x, Buffer @ 0x%08x)\n", + Lba, + Offset, + *NumBytes, + Buffer + )); + + // Localise the block size to avoid de-referencing pointers all the time + BlockSize =3D Instance->BlockSize; + + // The write must not span block boundaries. + // We need to check each variable individually because adding two large + // values together overflows. + if ((Offset >=3D BlockSize) || + (*NumBytes > BlockSize) || + ((Offset + *NumBytes) > BlockSize)) + { + DEBUG (( + DEBUG_ERROR, + "NorFlashWriteSingleBlock: ERROR - EFI_BAD_BUFFER_SIZE: (Offset=3D0x= %x + NumBytes=3D0x%x) > BlockSize=3D0x%x\n", + Offset, + *NumBytes, + BlockSize + )); + return EFI_BAD_BUFFER_SIZE; + } + + // We must have some bytes to write + if (*NumBytes =3D=3D 0) { + DEBUG (( + DEBUG_ERROR, + "NorFlashWriteSingleBlock: ERROR - EFI_BAD_BUFFER_SIZE: (Offset=3D0x= %x + NumBytes=3D0x%x) > BlockSize=3D0x%x\n", + Offset, + *NumBytes, + BlockSize + )); + return EFI_BAD_BUFFER_SIZE; + } + + // Pick 128bytes as a good start for word operations as opposed to erasi= ng the + // block and writing the data regardless if an erase is really needed. + // It looks like most individual NV variable writes are smaller than 128= bytes. + if (*NumBytes <=3D 128) { + // Check to see if we need to erase before programming the data into N= OR. + // If the destination bits are only changing from 1s to 0s we can just= write. + // After a block is erased all bits in the block is set to 1. + // If any byte requires us to erase we just give up and rewrite all of= it. + DoErase =3D FALSE; + BytesToWrite =3D *NumBytes; + CurOffset =3D Offset; + + while (BytesToWrite > 0) { + // Read full word from NOR, splice as required. A word is the smalle= st + // unit we can write. + Status =3D NorFlashRead ( + Instance, + Lba, + CurOffset & ~(0x3), + sizeof (Tmp), + &Tmp + ); + if (EFI_ERROR (Status)) { + return EFI_DEVICE_ERROR; + } + + // Physical address of word in NOR to write. + WordAddr =3D (CurOffset & ~(0x3)) + + GET_NOR_BLOCK_ADDRESS ( + Instance->RegionBaseAddress, + Lba, + BlockSize + ); + + // The word of data that is to be written. + TmpBuf =3D ReadUnaligned32 ((UINT32 *)(Buffer + (*NumBytes - BytesTo= Write))); + + // First do word aligned chunks. + if ((CurOffset & 0x3) =3D=3D 0) { + if (BytesToWrite >=3D 4) { + // Is the destination still in 'erased' state? + if (~Tmp !=3D 0) { + // Check to see if we are only changing bits to zero. + if ((Tmp ^ TmpBuf) & TmpBuf) { + DoErase =3D TRUE; + break; + } + } + + // Write this word to NOR + WordToWrite =3D TmpBuf; + CurOffset +=3D sizeof (TmpBuf); + BytesToWrite -=3D sizeof (TmpBuf); + } else { + // BytesToWrite < 4. Do small writes and left-overs + Mask =3D ~((~0) << (BytesToWrite * 8)); + // Mask out the bytes we want. + TmpBuf &=3D Mask; + // Is the destination still in 'erased' state? + if ((Tmp & Mask) !=3D Mask) { + // Check to see if we are only changing bits to zero. + if ((Tmp ^ TmpBuf) & TmpBuf) { + DoErase =3D TRUE; + break; + } + } + + // Merge old and new data. Write merged word to NOR + WordToWrite =3D (Tmp & ~Mask) | TmpBuf; + CurOffset +=3D BytesToWrite; + BytesToWrite =3D 0; + } + } else { + // Do multiple words, but starting unaligned. + if (BytesToWrite > (4 - (CurOffset & 0x3))) { + Mask =3D ((~0) << ((CurOffset & 0x3) * 8)); + // Mask out the bytes we want. + TmpBuf &=3D Mask; + // Is the destination still in 'erased' state? + if ((Tmp & Mask) !=3D Mask) { + // Check to see if we are only changing bits to zero. + if ((Tmp ^ TmpBuf) & TmpBuf) { + DoErase =3D TRUE; + break; + } + } + + // Merge old and new data. Write merged word to NOR + WordToWrite =3D (Tmp & ~Mask) | TmpBuf; + BytesToWrite -=3D (4 - (CurOffset & 0x3)); + CurOffset +=3D (4 - (CurOffset & 0x3)); + } else { + // Unaligned and fits in one word. + Mask =3D (~((~0) << (BytesToWrite * 8))) << ((CurOffset & 0x3) *= 8); + // Mask out the bytes we want. + TmpBuf =3D (TmpBuf << ((CurOffset & 0x3) * 8)) & Mask; + // Is the destination still in 'erased' state? + if ((Tmp & Mask) !=3D Mask) { + // Check to see if we are only changing bits to zero. + if ((Tmp ^ TmpBuf) & TmpBuf) { + DoErase =3D TRUE; + break; + } + } + + // Merge old and new data. Write merged word to NOR + WordToWrite =3D (Tmp & ~Mask) | TmpBuf; + CurOffset +=3D BytesToWrite; + BytesToWrite =3D 0; + } + } + + BlockAddress =3D GET_NOR_BLOCK_ADDRESS ( + Instance->RegionBaseAddress, + Lba, + BlockSize + ); + if (BlockAddress !=3D PrevBlockAddress) { + Status =3D NorFlashUnlockSingleBlockIfNecessary (Instance, BlockAd= dress); + if (EFI_ERROR (Status)) { + return EFI_DEVICE_ERROR; + } + + PrevBlockAddress =3D BlockAddress; + } + + Status =3D NorFlashWriteSingleWord (Instance, WordAddr, WordToWrite); + if (EFI_ERROR (Status)) { + return EFI_DEVICE_ERROR; + } + } + + // Exit if we got here and could write all the data. Otherwise do the + // Erase-Write cycle. + if (!DoErase) { + return EFI_SUCCESS; + } + } + + // Check we did get some memory. Buffer is BlockSize. + if (Instance->ShadowBuffer =3D=3D NULL) { + DEBUG ((DEBUG_ERROR, "FvbWrite: ERROR - Buffer not ready\n")); + return EFI_DEVICE_ERROR; + } + + // Read NOR Flash data into shadow buffer + Status =3D NorFlashReadBlocks ( + Instance, + Lba, + BlockSize, + Instance->ShadowBuffer + ); + if (EFI_ERROR (Status)) { + // Return one of the pre-approved error statuses + return EFI_DEVICE_ERROR; + } + + // Put the data at the appropriate location inside the buffer area + CopyMem ((VOID *)((UINTN)Instance->ShadowBuffer + Offset), Buffer, *NumB= ytes); + + // Write the modified buffer back to the NorFlash + Status =3D NorFlashWriteBlocks ( + Instance, + Lba, + BlockSize, + Instance->ShadowBuffer + ); + if (EFI_ERROR (Status)) { + // Return one of the pre-approved error statuses + return EFI_DEVICE_ERROR; + } + + return EFI_SUCCESS; +} + +/** + Read JEDEC ID of NOR flash device. + + @param[in] Instance NOR flash Instance of variable store region. + @param[out] JedecId JEDEC ID of NOR flash device. + + @retval EFI_SUCCESS The write is completed. +**/ +EFI_STATUS +NorFlashReadID ( + IN NOR_FLASH_INSTANCE *Instance, + OUT UINT8 JedecId[3] + ) +{ + UINT32 val; + + if ((Instance =3D=3D NULL) || (JedecId =3D=3D NULL)) { + return EFI_INVALID_PARAMETER; + } + + val =3D SPINOR_OP_RDID << CDNS_QSPI_FLASH_CMD_CTRL_REG_OPCODE_BIT_POS | + CDNS_QSPI_FLASH_CMD_CTRL_REG_READ_ENABLE << CDNS_QSPI_FLASH_CMD_CT= RL_REG_READEN_BIT_POS | + CDNS_QSPI_FLASH_CMD_CTRL_REG_NUM_DATA_BYTES (3); + + if (EFI_ERROR (CdnsQspiExecuteCommand (Instance, val))) { + return EFI_DEVICE_ERROR; + } + + val =3D MmioRead32 (Instance->HostRegisterBaseAddress + CDNS_QSPI_FLASH_= CMD_READ_DATA_REG_OFFSET); + + // Manu.ID field + JedecId[0] =3D (UINT8)val; + // Type field + JedecId[1] =3D (UINT8)(val >> 8); + // Capacity field + JedecId[2] =3D (UINT8)(val >> 16); + + DEBUG (( + DEBUG_INFO, + "Nor flash detected, Jedec ID, Manu.Id=3D%x Type=3D%x Capacity=3D%x \n= ", + JedecId[0], + JedecId[1], + JedecId[2] + )); + + return EFI_SUCCESS; +} diff --git a/Platform/ARM/N1Sdp/Drivers/CadenceQspiDxe/NorFlashFvb.c b/Plat= form/ARM/N1Sdp/Drivers/CadenceQspiDxe/NorFlashFvb.c new file mode 100644 index 000000000000..8281d4825dc9 --- /dev/null +++ b/Platform/ARM/N1Sdp/Drivers/CadenceQspiDxe/NorFlashFvb.c @@ -0,0 +1,647 @@ +/** @file + + Copyright (c) 2023, ARM Limited. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include "NorFlash.h" + +UINTN mFlashNvStorageVariableBase; + +/** + Initialize the FV Header and Variable Store Header + to support variable operations. + + @param[in] Instance Location to initialise the headers. + + @retval EFI_SUCCESS Fv init is done. + +**/ +EFI_STATUS +InitializeFvAndVariableStoreHeaders ( + IN NOR_FLASH_INSTANCE *Instance + ) +{ + EFI_STATUS Status; + VOID *Headers; + UINTN HeadersLength; + EFI_FIRMWARE_VOLUME_HEADER *FirmwareVolumeHeader; + VARIABLE_STORE_HEADER *VariableStoreHeader; + + if (!Instance->Initialized && Instance->Initialize) { + Instance->Initialize (Instance); + } + + HeadersLength =3D sizeof (EFI_FIRMWARE_VOLUME_HEADER) + + sizeof (EFI_FV_BLOCK_MAP_ENTRY) + + sizeof (VARIABLE_STORE_HEADER); + Headers =3D AllocateZeroPool (HeadersLength); + + FirmwareVolumeHeader =3D (EFI_FIRMWARE_VOLUME_HEADER *)Headers; + CopyGuid (&FirmwareVolumeHeader->FileSystemGuid, &gEfiSystemNvDataFvGuid= ); + FirmwareVolumeHeader->FvLength =3D + PcdGet32 (PcdFlashNvStorageVariableSize) + + PcdGet32 (PcdFlashNvStorageFtwWorkingSize) + + PcdGet32 (PcdFlashNvStorageFtwSpareSize); + FirmwareVolumeHeader->Signature =3D EFI_FVH_SIGNATURE; + FirmwareVolumeHeader->Attributes =3D EFI_FVB2_READ_ENABLED_CAP | + EFI_FVB2_READ_STATUS | + EFI_FVB2_STICKY_WRITE | + EFI_FVB2_MEMORY_MAPPED | + EFI_FVB2_ERASE_POLARITY | + EFI_FVB2_WRITE_STATUS | + EFI_FVB2_WRITE_ENABLED_CAP; + + FirmwareVolumeHeader->HeaderLength =3D sizeof (EFI_FIRMWARE_VOLUME_HEADE= R) + + sizeof (EFI_FV_BLOCK_MAP_ENTRY); + FirmwareVolumeHeader->Revision =3D EFI_FVH_REVISION; + FirmwareVolumeHeader->BlockMap[0].NumBlocks =3D Instance->LastBlock + 1; + FirmwareVolumeHeader->BlockMap[0].Length =3D Instance->BlockSize; + FirmwareVolumeHeader->BlockMap[1].NumBlocks =3D 0; + FirmwareVolumeHeader->BlockMap[1].Length =3D 0; + FirmwareVolumeHeader->Checksum =3D CalculateCheckSum16 ( + (UINT16 *)FirmwareVolume= Header, + FirmwareVolumeHeader->He= aderLength + ); + + VariableStoreHeader =3D (VOID *)((UINTN)Headers + + FirmwareVolumeHeader->HeaderLength); + CopyGuid (&VariableStoreHeader->Signature, &gEfiAuthenticatedVariableGui= d); + VariableStoreHeader->Size =3D PcdGet32 (PcdFlashNvStorageVariableSize) - + FirmwareVolumeHeader->HeaderLength; + VariableStoreHeader->Format =3D VARIABLE_STORE_FORMATTED; + VariableStoreHeader->State =3D VARIABLE_STORE_HEALTHY; + + // Install the combined super-header in the NorFlash + Status =3D FvbWrite (&Instance->FvbProtocol, 0, 0, &HeadersLength, Heade= rs); + + FreePool (Headers); + return Status; +} + +/** + Check the integrity of firmware volume header. + + @param[in] Instance Instance of Nor flash variable region. + + @retval EFI_SUCCESS The firmware volume is consistent. + @retval EFI_NOT_FOUND The firmware volume has been corrupted. + +**/ +EFI_STATUS +ValidateFvHeader ( + IN NOR_FLASH_INSTANCE *Instance + ) +{ + EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader; + VARIABLE_STORE_HEADER *VariableStoreHeader; + UINTN VariableStoreLength; + UINTN FvLength; + + FwVolHeader =3D (EFI_FIRMWARE_VOLUME_HEADER *)Instance->RegionBaseAddres= s; + + FvLength =3D PcdGet32 (PcdFlashNvStorageVariableSize) + + PcdGet32 (PcdFlashNvStorageFtwWorkingSize) + + PcdGet32 (PcdFlashNvStorageFtwSpareSize); + + if ( (FwVolHeader->Revision !=3D EFI_FVH_REVISION) + || (FwVolHeader->Signature !=3D EFI_FVH_SIGNATURE) + || (FwVolHeader->FvLength !=3D FvLength) + ) + { + DEBUG (( + DEBUG_ERROR, + "%a: No Firmware Volume header present\n", + __func__ + )); + return EFI_NOT_FOUND; + } + + // Check the Firmware Volume Guid + if (!CompareGuid (&FwVolHeader->FileSystemGuid, &gEfiSystemNvDataFvGuid)= ) { + DEBUG (( + DEBUG_ERROR, + "%a: Firmware Volume Guid non-compatible\n", + __func__ + )); + return EFI_NOT_FOUND; + } + + VariableStoreHeader =3D (VOID *)((UINTN)FwVolHeader + + FwVolHeader->HeaderLength); + + // Check the Variable Store Guid + if (!CompareGuid (&VariableStoreHeader->Signature, &gEfiVariableGuid) && + !CompareGuid ( + &VariableStoreHeader->Signature, + &gEfiAuthenticatedVariableGuid + )) + { + DEBUG (( + DEBUG_ERROR, + "%a: Variable Store Guid non-compatible\n", + __func__ + )); + return EFI_NOT_FOUND; + } + + VariableStoreLength =3D PcdGet32 (PcdFlashNvStorageVariableSize) - + FwVolHeader->HeaderLength; + if (VariableStoreHeader->Size !=3D VariableStoreLength) { + DEBUG (( + DEBUG_ERROR, + "%a: Variable Store Length does not match\n", + __func__ + )); + return EFI_NOT_FOUND; + } + + return EFI_SUCCESS; +} + +/** + Retrieves the attributes and current settings of the block. + + @param[in] This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOC= OL instance. + + @param[out] Attributes Pointer to EFI_FVB_ATTRIBUTES_2 in which the at= tributes and + current settings are returned. + Type EFI_FVB_ATTRIBUTES_2 is defined in + EFI_FIRMWARE_VOLUME_HEADER. + + @retval EFI_SUCCESS The firmware volume attributes were returned. + +**/ +EFI_STATUS +EFIAPI +FvbGetAttributes ( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, + OUT EFI_FVB_ATTRIBUTES_2 *Attributes + ) +{ + EFI_FVB_ATTRIBUTES_2 FlashFvbAttributes; + + FlashFvbAttributes =3D EFI_FVB2_READ_ENABLED_CAP | EFI_FVB2_READ_STATUS | + EFI_FVB2_WRITE_ENABLED_CAP | EFI_FVB2_WRITE_STATUS | + EFI_FVB2_STICKY_WRITE | EFI_FVB2_MEMORY_MAPPED | + EFI_FVB2_ERASE_POLARITY; + + *Attributes =3D FlashFvbAttributes; + + DEBUG ((DEBUG_INFO, "FvbGetAttributes(0x%X)\n", *Attributes)); + + return EFI_SUCCESS; +} + +/** + Sets configurable firmware volume attributes and returns the + new settings of the firmware volume. + + + @param[in] This EFI_FIRMWARE_VOLUME_BLOCK2_PR= OTOCOL instance. + + @param[in, out] Attributes On input, Attributes is a poi= nter to + EFI_FVB_ATTRIBUTES_2 that con= tains the desired + firmware volume settings. + On successful return, it cont= ains the new + settings of the firmware volu= me. + + @retval EFI_UNSUPPORTED The firmware volume attribute= s are not supported. + +**/ +EFI_STATUS +EFIAPI +FvbSetAttributes ( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, + IN OUT EFI_FVB_ATTRIBUTES_2 *Attributes + ) +{ + DEBUG (( + DEBUG_INFO, + "FvbSetAttributes(0x%X) is not supported\n", + *Attributes + )); + return EFI_UNSUPPORTED; +} + +/** + Retrieves the base address of a memory-mapped firmware volume. + This function should be called only for memory-mapped firmware volumes. + + @param[in] This EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL ins= tance. + + @param[out] Address Pointer to a caller-allocated + EFI_PHYSICAL_ADDRESS that, on successful + return from GetPhysicalAddress(), conta= ins the + base address of the firmware volume. + + @retval EFI_SUCCESS The firmware volume base address was re= turned. + +**/ +EFI_STATUS +EFIAPI +FvbGetPhysicalAddress ( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, + OUT EFI_PHYSICAL_ADDRESS *Address + ) +{ + NOR_FLASH_INSTANCE *Instance; + + Instance =3D INSTANCE_FROM_FVB_THIS (This); + + DEBUG (( + DEBUG_INFO, + "FvbGetPhysicalAddress(BaseAddress=3D0x%08x)\n", + Instance->RegionBaseAddress + )); + + ASSERT (Address !=3D NULL); + + *Address =3D Instance->RegionBaseAddress; + return EFI_SUCCESS; +} + +/** + Retrieves the size of the requested block. + It also returns the number of additional blocks with the identical size. + The GetBlockSize() function is used to retrieve the block map + (see EFI_FIRMWARE_VOLUME_HEADER). + + + @param[in] This EFI_FIRMWARE_VOLUME_BLOCK2_PROTOC= OL instance. + + @param[in] Lba Indicates the block whose size to= return + + @param[out] BlockSize Pointer to a caller-allocated UIN= TN in which + the size of the block is returned. + + @param[out] NumberOfBlocks Pointer to a caller-allocated UIN= TN in + which the number of consecutive b= locks, + starting with Lba, is returned. A= ll + blocks in this range have a size = of + BlockSize. + + @retval EFI_SUCCESS The firmware volume base address = was returned. + + @retval EFI_INVALID_PARAMETER The requested LBA is out of range. + +**/ +EFI_STATUS +EFIAPI +FvbGetBlockSize ( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, + IN EFI_LBA Lba, + OUT UINTN *BlockSize, + OUT UINTN *NumberOfBlocks + ) +{ + EFI_STATUS Status; + NOR_FLASH_INSTANCE *Instance; + + Instance =3D INSTANCE_FROM_FVB_THIS (This); + + DEBUG (( + DEBUG_INFO, + "FvbGetBlockSize(Lba=3D%ld, BlockSize=3D0x%x, LastBlock=3D%ld)\n", + Lba, + Instance->BlockSize, + Instance->LastBlock + )); + + if (Lba > Instance->LastBlock) { + DEBUG (( + DEBUG_ERROR, + "FvbGetBlockSize: ERROR - Parameter LBA %ld is beyond the last Lba (= %ld).\n", + Lba, + Instance->LastBlock + )); + Status =3D EFI_INVALID_PARAMETER; + } else { + // This is easy because in this platform each NorFlash device has equa= l sized blocks. + *BlockSize =3D (UINTN)Instance->BlockSize; + *NumberOfBlocks =3D (UINTN)(Instance->LastBlock - Lba + 1); + + DEBUG (( + DEBUG_INFO, + "FvbGetBlockSize: *BlockSize=3D0x%x, *NumberOfBlocks=3D0x%x.\n", + *BlockSize, + *NumberOfBlocks + )); + + Status =3D EFI_SUCCESS; + } + + return Status; +} + +/** + Reads the specified number of bytes into a buffer from the specified bloc= k. + + The Read() function reads the requested number of bytes from the + requested block and stores them in the provided buffer. + + @param[in] This EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL= instance. + + @param[in] Lba The starting logical block index fr= om which to read + + @param[in] Offset Offset into the block at which to b= egin reading. + + @param[in, out] NumBytes Pointer to a UINTN. + At entry, *NumBytes contains the to= tal size of the + buffer. *NumBytes should have a non= zero value. + At exit, *NumBytes contains the tot= al number of + bytes read. + + @param[in, out] Buffer Pointer to a caller-allocated buffe= r that will be + used to hold the data that is read. + + @retval EFI_SUCCESS The firmware volume was read succes= sfully, and + contents are in Buffer. + + @retval EFI_BAD_BUFFER_SIZE Read attempted across an LBA bounda= ry. + + @retval EFI_DEVICE_ERROR The block device is not functioning= correctly and + could not be read. + +**/ +EFI_STATUS +EFIAPI +FvbRead ( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, + IN EFI_LBA Lba, + IN UINTN Offset, + IN OUT UINTN *NumBytes, + IN OUT UINT8 *Buffer + ) +{ + EFI_STATUS Status; + UINTN BlockSize; + NOR_FLASH_INSTANCE *Instance; + + Instance =3D INSTANCE_FROM_FVB_THIS (This); + + DEBUG (( + DEBUG_INFO, + "FvbRead(Parameters: Lba=3D%ld, Offset=3D0x%x, *NumBytes=3D0x%x, Buffe= r @ 0x%08x)\n", + Instance->StartLba + Lba, + Offset, + *NumBytes, + Buffer + )); + + if (!Instance->Initialized && Instance->Initialize) { + Instance->Initialize (Instance); + } + + BlockSize =3D Instance->BlockSize; + + DEBUG (( + DEBUG_INFO, + "FvbRead: Check if (Offset=3D0x%x + NumBytes=3D0x%x) <=3D BlockSize=3D= 0x%x\n", + Offset, + *NumBytes, + BlockSize + )); + + // The read must not span block boundaries. + // We need to check each variable individually because adding two large + // values together overflows. + if ((Offset >=3D BlockSize) || + (*NumBytes > BlockSize) || + ((Offset + *NumBytes) > BlockSize)) + { + DEBUG (( + DEBUG_ERROR, + "FvbRead: ERROR - EFI_BAD_BUFFER_SIZE: (Offset=3D0x%x + NumBytes=3D0= x%x) > BlockSize=3D0x%x\n", + Offset, + *NumBytes, + BlockSize + )); + return EFI_BAD_BUFFER_SIZE; + } + + // We must have some bytes to read + if (*NumBytes =3D=3D 0) { + return EFI_BAD_BUFFER_SIZE; + } + + // Decide if we are doing full block reads or not. + if (*NumBytes % BlockSize !=3D 0) { + Status =3D NorFlashRead ( + Instance, + Instance->StartLba + Lba, + Offset, + *NumBytes, + Buffer + ); + } else { + // Read NOR Flash data into shadow buffer + Status =3D NorFlashReadBlocks ( + Instance, + Instance->StartLba + Lba, + BlockSize, + Buffer + ); + } + + if (EFI_ERROR (Status)) { + // Return one of the pre-approved error statuses + return EFI_DEVICE_ERROR; + } + + return EFI_SUCCESS; +} + +/** + Writes the specified number of bytes from the input buffer to the block. + + @param[in] This EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCO= L instance. + + @param[in] Lba The starting logical block index t= o write to. + + @param[in] Offset Offset into the block at which to = begin writing. + + @param[in, out] NumBytes The pointer to a UINTN. + At entry, *NumBytes contains the t= otal size of the + buffer. + At exit, *NumBytes contains the to= tal number of + bytes actually written. + + @param[in] Buffer The pointer to a caller-allocated = buffer that + contains the source for the write. + + @retval EFI_SUCCESS The firmware volume was written su= ccessfully. + +**/ +EFI_STATUS +EFIAPI +FvbWrite ( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, + IN EFI_LBA Lba, + IN UINTN Offset, + IN OUT UINTN *NumBytes, + IN UINT8 *Buffer + ) +{ + NOR_FLASH_INSTANCE *Instance; + + Instance =3D INSTANCE_FROM_FVB_THIS (This); + + return NorFlashWriteSingleBlock ( + Instance, + Instance->StartLba + Lba, + Offset, + NumBytes, + Buffer + ); +} + +/** + Erases and initialises a firmware volume block. + + @param[in] This EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL + + @param[in] ... The variable argument list is a lis= t of tuples. + Each tuple describes a range of LBA= s to erase + and consists of the following: + - An EFI_LBA that indicates the sta= rting LBA + - A UINTN that indicates the number= of blocks + to erase. + + The list is terminated with an + EFI_LBA_LIST_TERMINATOR. + + @retval EFI_SUCCESS The erase request successfully comp= leted. + + @retval EFI_ACCESS_DENIED The firmware volume is in the Write= Disabled + state. + + @retval EFI_DEVICE_ERROR The block device is not functioning= correctly + and could not be written. + The firmware device may have been p= artially + erased. + + @retval EFI_INVALID_PARAMETER One or more of the LBAs listed in th= e variable + argument list do not exist in the fi= rmware + volume. + +**/ +EFI_STATUS +EFIAPI +FvbEraseBlocks ( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, + ... + ) +{ + EFI_STATUS Status; + VA_LIST Args; + UINTN BlockAddress; // Physical address of Lba to erase + EFI_LBA StartingLba; // Lba from which we start erasing + UINTN NumOfLba; // Number of Lba blocks to erase + NOR_FLASH_INSTANCE *Instance; + + Instance =3D INSTANCE_FROM_FVB_THIS (This); + + DEBUG ((DEBUG_INFO, "FvbEraseBlocks()\n")); + + Status =3D EFI_SUCCESS; + + // Before erasing, check the entire list of parameters to ensure + // all specified blocks are valid + + VA_START (Args, This); + do { + // Get the Lba from which we start erasing + StartingLba =3D VA_ARG (Args, EFI_LBA); + + // Have we reached the end of the list? + if (StartingLba =3D=3D EFI_LBA_LIST_TERMINATOR) { + break; + } + + // How many Lba blocks are we requested to erase? + NumOfLba =3D VA_ARG (Args, UINT32); + + // All blocks must be within range + DEBUG (( + DEBUG_INFO, + "FvbEraseBlocks: Check if: ( StartingLba=3D%ld + NumOfLba=3D%d - 1 )= > LastBlock=3D%ld.\n", + Instance->StartLba + StartingLba, + NumOfLba, + Instance->LastBlock + )); + if ((NumOfLba =3D=3D 0) || + ((Instance->StartLba + StartingLba + NumOfLba - 1) > + Instance->LastBlock)) + { + VA_END (Args); + DEBUG (( + DEBUG_ERROR, + "FvbEraseBlocks: ERROR - Lba range goes past the last Lba.\n" + )); + return EFI_INVALID_PARAMETER; + } + } while (TRUE); + + VA_END (Args); + + VA_START (Args, This); + do { + // Get the Lba from which we start erasing + StartingLba =3D VA_ARG (Args, EFI_LBA); + + // Have we reached the end of the list? + if (StartingLba =3D=3D EFI_LBA_LIST_TERMINATOR) { + // Exit the while loop + break; + } + + // How many Lba blocks are we requested to erase? + NumOfLba =3D VA_ARG (Args, UINT32); + + // Go through each one and erase it + while (NumOfLba > 0) { + // Get the physical address of Lba to erase + BlockAddress =3D GET_NOR_BLOCK_ADDRESS ( + Instance->RegionBaseAddress, + Instance->StartLba + StartingLba, + Instance->BlockSize + ); + + // Erase it + DEBUG (( + DEBUG_INFO, + "FvbEraseBlocks: Erasing Lba=3D%ld @ 0x%08x.\n", + Instance->StartLba + StartingLba, + BlockAddress + )); + Status =3D NorFlashUnlockAndEraseSingleBlock (Instance, BlockAddress= ); + if (EFI_ERROR (Status)) { + VA_END (Args); + return EFI_DEVICE_ERROR; + } + + // Move to the next Lba + StartingLba++; + NumOfLba--; + } + } while (TRUE); + + VA_END (Args); + + return Status; +} --=20 2.25.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 (#111311): https://edk2.groups.io/g/devel/message/111311 Mute This Topic: https://groups.io/mt/102625036/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- From nobody Wed May 15 11:47:12 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+111312+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+111312+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=arm.com ARC-Seal: i=1; a=rsa-sha256; t=1700135174; cv=none; d=zohomail.com; s=zohoarc; b=dkHkR0QCBhCREqukeQGWsJNfbC0/g5WVrPmPDlxF238Y1bWG+H2kD85tt12dJuymMLoVyEIwexVs7aLLs3GjKZ7Mxd1LYgldkTqL2M8uq4VXtzAfU9GoFwgZJmBbKGzZoMvUTJDyfh2qcwxhYNeTr0seG4oFZoVHsXZUGrP7GTk= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1700135174; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:Reply-To:References:Sender:Subject:Subject:To:To:Message-Id; bh=uefoWV22uYtPe71abUc0bffTETNVO/GyaZ30i20Bqzk=; b=jUaHMuKOBH8UciWYyWkNxPlOIICNdcumbqjftmxvwjMRxrRLpM0mSum5Y1ULxIO0T0KMeZ1neSFfbGx5v5iHh7sUV2FBq3r/SdmfdYvhffDbDnOmRPQebbLxhe51PwcZge3FwrYkQyPvzrPtIGBZEbq0q+KeHbsfPU+UYPWlS2o= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+111312+1787277+3901457@groups.io; dmarc=fail header.from= (p=none dis=none) Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1700135174552511.18413538193306; Thu, 16 Nov 2023 03:46:14 -0800 (PST) Return-Path: DKIM-Signature: a=rsa-sha256; bh=7wr+OnuMJrchI5jaf9LJlPQtPY6EtwY3ephy/LuP3So=; c=relaxed/simple; d=groups.io; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References:MIME-Version:Precedence:List-Subscribe:List-Help:Sender:List-Id:Mailing-List:Delivered-To:Reply-To:List-Unsubscribe-Post:List-Unsubscribe:Content-Transfer-Encoding; s=20140610; t=1700135174; v=1; b=aQ+D2QcP/wJBSayFHT2bt8psS/Sihtts558jqHM/oBfZ1Ap8DDgDXBGE95pPYJq1YxkrY8q2 DOvwm8HNlTmpFIytP46Pvoz308exw4ikc06CEarZ/XmXpFwBa/KChfvprwJ235lJ7ljhKBEmM5h B9gk7QT5GWZL9+HixH0R8R3Y= X-Received: by 127.0.0.2 with SMTP id RDRbYY1788612xGy8ukqiycV; Thu, 16 Nov 2023 03:46:14 -0800 X-Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by mx.groups.io with SMTP id smtpd.web10.4907.1700135173578886804 for ; Thu, 16 Nov 2023 03:46:13 -0800 X-Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 536231650; Thu, 16 Nov 2023 03:46:59 -0800 (PST) X-Received: from usa.arm.com (a077434.blr.arm.com [10.162.17.62]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 94A323F6C4; Thu, 16 Nov 2023 03:46:11 -0800 (PST) From: "sahil" To: devel@edk2.groups.io Cc: Ard Biesheuvel , Leif Lindholm , Sami Mujawar , Sahil Subject: [edk2-devel] [edk2-platforms][PATCH V1 4/5] Platform/ARM/N1Sdp: Persistent storage for N1Sdp Date: Thu, 16 Nov 2023 17:15:53 +0530 Message-Id: <20231116114554.4055517-5-sahil@arm.com> In-Reply-To: <20231116114554.4055517-1-sahil@arm.com> References: <20231116114554.4055517-1-sahil@arm.com> MIME-Version: 1.0 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,sahil@arm.com List-Unsubscribe-Post: List-Unsubscribe=One-Click List-Unsubscribe: X-Gm-Message-State: DpHTa8XiEwp57Smuh86y9a0jx1787277AA= Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1700135176617100019 Content-Type: text/plain; charset="utf-8" Enable persistent storage on QSPI flash device. Signed-off-by: sahil Reviewed-by: Thomas Abraham --- Platform/ARM/N1Sdp/N1SdpPlatform.dsc | 20 ++++++++++++++------ Platform/ARM/N1Sdp/N1SdpPlatform.fdf | 4 +++- 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/Platform/ARM/N1Sdp/N1SdpPlatform.dsc b/Platform/ARM/N1Sdp/N1Sd= pPlatform.dsc index d04b22d3ef51..10fe2db9e1b1 100644 --- a/Platform/ARM/N1Sdp/N1SdpPlatform.dsc +++ b/Platform/ARM/N1Sdp/N1SdpPlatform.dsc @@ -4,7 +4,7 @@ # This provides platform specific component descriptions and libraries that # conform to EFI/Framework standards. # -# Copyright (c) 2018 - 2021, ARM Limited. All rights reserved.
+# Copyright (c) 2018 - 2023, ARM Limited. All rights reserved.
# # SPDX-License-Identifier: BSD-2-Clause-Patent # @@ -44,6 +44,9 @@ # file explorer library support FileExplorerLib|MdeModulePkg/Library/FileExplorerLib/FileExplorerLib.inf =20 + # NOR flash support + NorFlashInfoLib|EmbeddedPkg/Library/NorFlashInfoLib/NorFlashInfoLib.inf + [LibraryClasses.common.SEC] HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAlloc= ationLib.inf @@ -161,11 +164,9 @@ # ACPI Table Version gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiExposedTableVersions|0x20 =20 - # Runtime Variable storage - gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvStoreReserved|0 - gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvModeEnable|TRUE - gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize|0x2000 - gEfiMdeModulePkgTokenSpaceGuid.PcdMaxAuthVariableSize|0x2800 + # NOR flash support + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase|0x18F00000 + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize|0x00020000 =20 ##########################################################################= ###### # @@ -197,6 +198,12 @@ gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x8000000F } =20 + # NOR flash support + Platform/ARM/N1Sdp/Drivers/CadenceQspiDxe/CadenceQspiDxe.inf { + + NorFlashPlatformLib|Silicon/ARM/NeoverseN1Soc/Library/NorFlashLib/No= rFlashLib.inf + } + # Architectural Protocols ArmPkg/Drivers/CpuDxe/CpuDxe.inf ArmPkg/Drivers/ArmGic/ArmGicDxe.inf @@ -217,6 +224,7 @@ MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf { NULL|MdeModulePkg/Library/VarCheckUefiLib/VarCheckUefiLib.inf + NULL|EmbeddedPkg/Library/NvVarStoreFormattedLib/NvVarStoreFormattedL= ib.inf BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf } =20 diff --git a/Platform/ARM/N1Sdp/N1SdpPlatform.fdf b/Platform/ARM/N1Sdp/N1Sd= pPlatform.fdf index e5e24ea50294..4329f892f7c5 100644 --- a/Platform/ARM/N1Sdp/N1SdpPlatform.fdf +++ b/Platform/ARM/N1Sdp/N1SdpPlatform.fdf @@ -1,7 +1,7 @@ ## @file # FDF file of N1Sdp # -# Copyright (c) 2018 - 2021, ARM Limited. All rights reserved.
+# Copyright (c) 2018 - 2023, ARM Limited. All rights reserved.
# # SPDX-License-Identifier: BSD-2-Clause-Patent ## @@ -140,6 +140,8 @@ READ_LOCK_STATUS =3D TRUE INF ArmPkg/Drivers/GenericWatchdogDxe/GenericWatchdogDxe.inf INF ArmPkg/Drivers/TimerDxe/TimerDxe.inf =20 + INF Platform/ARM/N1Sdp/Drivers/CadenceQspiDxe/CadenceQspiDxe.inf + INF Platform/ARM/Drivers/BootMonFs/BootMonFs.inf INF MdeModulePkg/Universal/PCD/Dxe/Pcd.inf =20 --=20 2.25.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 (#111312): https://edk2.groups.io/g/devel/message/111312 Mute This Topic: https://groups.io/mt/102625037/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- From nobody Wed May 15 11:47:12 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) client-ip=66.175.222.108; envelope-from=bounce+27952+111313+1787277+3901457@groups.io; helo=mail02.groups.io; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+111313+1787277+3901457@groups.io; dmarc=fail(p=none dis=none) header.from=arm.com ARC-Seal: i=1; a=rsa-sha256; t=1700135176; cv=none; d=zohomail.com; s=zohoarc; b=R6np8HGFVhIQjcUtd870dJloLpOw0azFmTlzmtNoY6iafd+m4M43jHZWpT8j3DFllJLm0Mn6f3GtDdUpCsQn/z6mDzWmEg9uR7iAZxgLaPCV66fWlza/UIpyJzsX6zNd0g15aKSGHVb9Jc0Ba8WRl8iA0kFb/y5kMyfDGt4KfyA= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1700135176; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:Reply-To:References:Sender:Subject:Subject:To:To:Message-Id; bh=wfbJO9z2b83WKTNu/N1/OPWrmZPfTXFR1s3sgfqxaqw=; b=MBHCRt5xWhRrGmptOZzW+Pnrc5r9tGWgUMTr8GnkSUSBpkRX8anMucVX90melFX1QcH5HrY9R5bivFkE606nQ/U6sjVPiDmmy51YbaWNKNHuoRW6MZXPY3NYp0wcItATTHOj4q2uanjCqx7KIUuyJS+pxM1hDK9eG4qyltevMNQ= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce+27952+111313+1787277+3901457@groups.io; dmarc=fail header.from= (p=none dis=none) Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by mx.zohomail.com with SMTPS id 1700135176602826.1996023073831; Thu, 16 Nov 2023 03:46:16 -0800 (PST) Return-Path: DKIM-Signature: a=rsa-sha256; bh=MYY6q+pBHrmJdyTgsXoo7XW5F7B4dSpd0/jvXy12VMU=; c=relaxed/simple; d=groups.io; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References:MIME-Version:Precedence:List-Subscribe:List-Help:Sender:List-Id:Mailing-List:Delivered-To:Reply-To:List-Unsubscribe-Post:List-Unsubscribe:Content-Transfer-Encoding; s=20140610; t=1700135176; v=1; b=YunOzombAha10SZOnnN0epP/XU5iJ/6Wp1iah4pq/6t+Hn9S/Y79jKJsd89KVCren0zRxB57 Jts7bIJMutoWec0KQ/usUaFHfIwaWTmfyiHBgEBEiVkLCthGFQXlmefXhE8yxXL2CdxmBuIZ5FO s1nBuut1gcfigd7/4TCveLwM= X-Received: by 127.0.0.2 with SMTP id wRIAYY1788612xc7g6HD9Qa9; Thu, 16 Nov 2023 03:46:16 -0800 X-Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by mx.groups.io with SMTP id smtpd.web10.4908.1700135175704958907 for ; Thu, 16 Nov 2023 03:46:15 -0800 X-Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 797B41650; Thu, 16 Nov 2023 03:47:01 -0800 (PST) X-Received: from usa.arm.com (a077434.blr.arm.com [10.162.17.62]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id BA8F93F6C4; Thu, 16 Nov 2023 03:46:13 -0800 (PST) From: "sahil" To: devel@edk2.groups.io Cc: Ard Biesheuvel , Leif Lindholm , Sami Mujawar , Sahil Subject: [edk2-devel] [edk2-platforms][PATCH V1 5/5] Platform/ARM/N1Sdp: Enable FaultTolerantWrite Dxe driver for N1Sdp Date: Thu, 16 Nov 2023 17:15:54 +0530 Message-Id: <20231116114554.4055517-6-sahil@arm.com> In-Reply-To: <20231116114554.4055517-1-sahil@arm.com> References: <20231116114554.4055517-1-sahil@arm.com> MIME-Version: 1.0 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,sahil@arm.com List-Unsubscribe-Post: List-Unsubscribe=One-Click List-Unsubscribe: X-Gm-Message-State: rkci5Gd1lOtq4dpUZMkq4kSax1787277AA= Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @groups.io) X-ZM-MESSAGEID: 1700135178602100023 Content-Type: text/plain; charset="utf-8" Signed-off-by: sahil Reviewed-by: Thomas Abraham --- Platform/ARM/N1Sdp/N1SdpPlatform.dsc | 5 +++++ Platform/ARM/N1Sdp/N1SdpPlatform.fdf | 1 + 2 files changed, 6 insertions(+) diff --git a/Platform/ARM/N1Sdp/N1SdpPlatform.dsc b/Platform/ARM/N1Sdp/N1Sd= pPlatform.dsc index 10fe2db9e1b1..703829bbac99 100644 --- a/Platform/ARM/N1Sdp/N1SdpPlatform.dsc +++ b/Platform/ARM/N1Sdp/N1SdpPlatform.dsc @@ -165,6 +165,10 @@ gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiExposedTableVersions|0x20 =20 # NOR flash support + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase|0x18F40000 + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize|0x00020000 + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase|0x18F20000 + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize|0x00020000 gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase|0x18F00000 gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize|0x00020000 =20 @@ -227,6 +231,7 @@ NULL|EmbeddedPkg/Library/NvVarStoreFormattedLib/NvVarStoreFormattedL= ib.inf BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf } + MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf =20 # ACPI Support MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf diff --git a/Platform/ARM/N1Sdp/N1SdpPlatform.fdf b/Platform/ARM/N1Sdp/N1Sd= pPlatform.fdf index 4329f892f7c5..17d370a371cf 100644 --- a/Platform/ARM/N1Sdp/N1SdpPlatform.fdf +++ b/Platform/ARM/N1Sdp/N1SdpPlatform.fdf @@ -90,6 +90,7 @@ READ_LOCK_STATUS =3D TRUE INF MdeModulePkg/Universal/Metronome/Metronome.inf INF MdeModulePkg/Universal/ResetSystemRuntimeDxe/ResetSystemRuntimeDxe.i= nf INF MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf + INF MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.i= nf INF MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRu= ntimeDxe.inf INF MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf INF MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf --=20 2.25.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 (#111313): https://edk2.groups.io/g/devel/message/111313 Mute This Topic: https://groups.io/mt/102625038/1787277 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-